Various relay selection changes

This commit is contained in:
Jon Staab 2024-03-06 11:21:22 -08:00
parent 7a80ac53ff
commit 2041ec6a7d
30 changed files with 102 additions and 96 deletions

View File

@ -55,7 +55,9 @@
external
href="https://info.coracle.social">
<img alt="App Logo" src={import.meta.env.VITE_LOGO_URL || "/images/logo.png"} class="w-12" />
<h1 class="staatliches text-[2.6em] leading-none -mb-[0.1em]">{appName}</h1>
<h1 class="staatliches -mb-[0.1em] leading-none" style={`font-size: ${appName.length / 5}em`}>
{appName}
</h1>
</Anchor>
<MenuDesktopItem path="/notes">Feed</MenuDesktopItem>
{#if !$env.FORCE_GROUP && $env.PLATFORM_RELAYS.length === 0}
@ -101,8 +103,10 @@
<div class="staatliches block flex h-8 gap-2 px-8 text-neutral-500 dark:text-tinted-600">
<Anchor external class="hover:text-neutral-200 dark:hover:text-tinted-200" href="/terms.html"
>Terms</Anchor> /
<Anchor external class="hover:text-neutral-200 dark:hover:text-tinted-200" href="/privacy.html"
>Privacy</Anchor>
<Anchor
external
class="hover:text-neutral-200 dark:hover:text-tinted-200"
href="/privacy.html">Privacy</Anchor>
</div>
{#if subMenu === "settings"}
<MenuDesktopSecondary onEscape={closeSubMenu}>
@ -155,7 +159,9 @@
{#if s.pubkey !== $pubkey}
<MenuItem class="py-4" on:click={() => pubkey.set(s.pubkey)}>
<div class="flex items-center gap-2">
<PersonCircle class="h-8 w-8 border border-solid border-tinted-200" pubkey={s.pubkey} />
<PersonCircle
class="h-8 w-8 border border-solid border-tinted-200"
pubkey={s.pubkey} />
{displayPubkey(s.pubkey)}
</div>
</MenuItem>

View File

@ -11,9 +11,19 @@
import {themeColors} from "src/partials/state"
import Anchor from "src/partials/Anchor.svelte"
import {router} from "src/app/router"
import {canSign, writable, getReplyFilters, load, isDeleted, subscribe, pubkey} from "src/engine"
import {
hints,
canSign,
getRelaysFromFilters,
writable,
getReplyFilters,
forcePlatformRelays,
load,
isDeleted,
subscribe,
pubkey,
} from "src/engine"
export let relays
export let filters
export let group = null
@ -41,7 +51,7 @@
onMount(() => {
const sub = subscribe({
filters,
relays: relays.concat(LOCAL_RELAY_URL),
relays: forcePlatformRelays(getRelaysFromFilters(filters)).concat(LOCAL_RELAY_URL),
onEvent: batch(300, chunk => {
events.update($events => {
for (const e of chunk) {
@ -56,7 +66,10 @@
})
// Load deletes for these events
load({relays, filters: getReplyFilters(chunk, {kinds: [5]})})
load({
relays: hints.merge(chunk.map(e => hints.EventChildren(e))).getUrls(),
filters: getReplyFilters(chunk, {kinds: [5]}),
})
}),
})
@ -100,7 +113,7 @@
eventContent: getEventContent,
eventStartEditable: false,
eventDragMinDistance: 10000,
eventTextColor: $themeColors['neutral-900'],
eventTextColor: $themeColors["neutral-900"],
longPressDelay: 10000,
buttonText: {
today: "Today",

View File

@ -24,6 +24,7 @@
export let relays = []
export let filter: DynamicFilter = {}
export let anchor = null
export let skipCache = false
export let shouldDisplay = null
export let shouldListen = false
export let hideControls = false
@ -46,7 +47,13 @@
? $searchableRelays
: getRelaysFromFilters(compileFilters([filter]))
return forcePlatformRelays(hints.scenario([selection]).getUrls()).concat(LOCAL_RELAY_URL)
const result = forcePlatformRelays(hints.scenario([selection]).getUrls())
if (!skipCache) {
result.push(LOCAL_RELAY_URL)
}
return result
}
const loadMore = () => feed.load(5)

View File

@ -5,8 +5,8 @@
import {router} from "src/app/router"
export let group
export let relays
const filter = group ? {kinds: [30402], "#a": [group]} : {kinds: [30402]}
const createListing = () => router.at("notes/create").qp({type: "listing", group}).open()
</script>
@ -15,4 +15,4 @@
<Anchor button accent on:click={createListing}>Create a listing</Anchor>
</Card>
<Feed hideControls {relays} filter={{kinds: [30402], "#a": [group]}} />
<Feed hideControls {filter} />

View File

@ -138,7 +138,7 @@
const broadcast = () => {
Publisher.publish({
event: note,
relays: hints.Outbox().getUrls(),
relays: hints.WriteRelays().getUrls(),
})
toast.show("info", "Note has been re-published!")

View File

@ -1,6 +1,6 @@
<script lang="ts">
import cx from "classnames"
import {Tags, addressToNaddr} from "paravel"
import {Tags, encodeAddress, addressToNaddr} from "paravel"
import {commaFormat} from "hurdak"
import FlexColumn from "src/partials/FlexColumn.svelte"
import Carousel from "src/partials/Carousel.svelte"
@ -22,8 +22,8 @@
const {title, summary, location, status} = tags.asObject()
const [price = 0, code = "SAT"] = tags.get("price")?.drop(1).valueOf() || []
const address = hints.address(note)
const editLink = router.at("listings").of(address).at("edit").toString()
const deleteLink = router.at("listings").of(address).at("delete").toString()
const editLink = router.at("listings").of(encodeAddress(address)).at("edit").toString()
const deleteLink = router.at("listings").of(encodeAddress(address)).at("delete").toString()
const sendMessage = () => {
const naddr = addressToNaddr(address)

View File

@ -42,7 +42,7 @@
)
load({
relays: hints.Inbox().getUrls(),
relays: hints.ReadRelays().getUrls(),
filters: [{limit: 1000, kinds: [1986], "#l": ["review/relay"]}],
onEvent: event => {
reviews = reviews.concat(event)

View File

@ -7,8 +7,6 @@
follows,
compileFilters,
getPubkeysWithDefaults,
getRelaysFromFilters,
forcePlatformRelays,
loadGroupMessages,
} from "src/engine"
@ -21,11 +19,10 @@
}
const filters = compileFilters([filter])
const relays = forcePlatformRelays(getRelaysFromFilters(filters))
if ($env.FORCE_GROUP) {
loadGroupMessages([$env.FORCE_GROUP])
}
</script>
<Calendar {filters} {relays} />
<Calendar {filters} />

View File

@ -56,7 +56,7 @@
{/if}
{#key key}
<Feed showGroup {filter} {relays}>
<Feed skipCache showGroup {filter} {relays}>
<div slot="controls">
{#if $canSign}
{#if $userLists.length > 0}

View File

@ -1,7 +1,7 @@
<script>
import {onMount} from "svelte"
import {whereEq, uniq, without} from "ramda"
import {noteKinds, LOCAL_RELAY_URL} from "src/util/nostr"
import {whereEq, without} from "ramda"
import {noteKinds} from "src/util/nostr"
import {getKey} from "src/util/router"
import {themeBackgroundGradient} from "src/partials/state"
import FlexColumn from "src/partials/FlexColumn.svelte"
@ -26,7 +26,6 @@
publishGroupEntryRequest,
groupRequests,
deriveGroup,
getGroupReqInfo,
deriveAdminKeyForGroup,
deriveSharedKeyForGroup,
deriveGroupStatus,
@ -46,8 +45,6 @@
requests.filter(whereEq({group: address, resolved: false})),
)
const info = getGroupReqInfo(address)
const setActiveTab = tab =>
router
.at("groups")
@ -64,7 +61,6 @@
let tabs
$: relays = uniq((relays || info.relays).concat(LOCAL_RELAY_URL))
$: loadPubkeys($group.members || [])
$: {
@ -131,15 +127,11 @@
{#if $canSign}
<NoteCreateInline group={address} />
{/if}
<Feed
shouldListen
hideControls
filter={{kinds: without([30402], noteKinds), "#a": [address]}}
relays={address.startsWith("35834:") ? [LOCAL_RELAY_URL] : relays} />
<Feed shouldListen hideControls filter={{kinds: without([30402], noteKinds), "#a": [address]}} />
{:else if activeTab === "calendar"}
<Calendar group={address} filters={[{kinds: [31923], "#a": [address]}]} {relays} />
<Calendar group={address} filters={[{kinds: [31923], "#a": [address]}]} />
{:else if activeTab === "market"}
<GroupMarket group={address} {relays} />
<GroupMarket group={address} />
{:else if activeTab === "members"}
<FlexColumn>
{#each $group.members || [] as pubkey (pubkey)}

View File

@ -4,6 +4,7 @@
import {partition, assoc} from "ramda"
import {now} from "paravel"
import {fuzzy, createScroller} from "src/util/misc"
import {giftWrapKinds} from "src/util/nostr"
import {getModal} from "src/partials/state"
import Anchor from "src/partials/Anchor.svelte"
import Input from "src/partials/Input.svelte"
@ -46,7 +47,7 @@
load({
relays,
filters: [{kinds: [1059, 1060], "#p": recipients, since}],
filters: [{kinds: giftWrapKinds, "#p": recipients, since}],
})
load({

View File

@ -93,7 +93,7 @@
onMount(() => {
load({
relays: hints.Inbox().getUrls(),
relays: hints.ReadRelays().getUrls(),
filters: [
{
kinds: [Handlerinformation],

View File

@ -133,7 +133,7 @@
if (!opts.groups.length) {
Publisher.publish({
event: quote,
relays: hints.Outbox().getUrls(),
relays: hints.WriteRelays().getUrls(),
})
}
}

View File

@ -80,25 +80,13 @@
loadGroupMessages()
loadNotifications()
const unsubUnreadNotifications = unreadNotifications.subscribe(events => {
if (activeTab !== "Groups") {
markAsSeen(events)
}
})
const unsubUnreadGroupNotifications = unreadGroupNotifications.subscribe(events => {
if (activeTab === "Groups") {
markAsSeen(events)
}
})
const scroller = createScroller(async () => {
limit += 4
})
return () => {
unsubUnreadNotifications()
unsubUnreadGroupNotifications()
markAsSeen($unreadNotifications)
markAsSeen($unreadGroupNotifications)
scroller.stop()
}
})
@ -108,15 +96,15 @@
<div slot="tab" let:tab class="flex gap-2">
<div>{tab}</div>
{#if tab === tabs[0] && unreadMainNotifications.length > 0}
<div class="h-6 rounded-full bg-neutral-600 px-2">
<div class="h-6 rounded-full bg-neutral-700 px-2">
{unreadMainNotifications.length}
</div>
{:else if tab === tabs[1] && unreadReactionNotifications.length > 0}
<div class="h-6 rounded-full bg-neutral-600 px-2">
<div class="h-6 rounded-full bg-neutral-700 px-2">
{unreadReactionNotifications.length}
</div>
{:else if tab === tabs[2] && $unreadGroupNotifications.length > 0}
<div class="h-6 rounded-full bg-neutral-600 px-2">
<div class="h-6 rounded-full bg-neutral-700 px-2">
{$unreadGroupNotifications.length}
</div>
{/if}

View File

@ -56,5 +56,5 @@
"#r": [$relay.url],
}} />
{:else}
<Feed {shouldDisplay} relays={[$relay.url]} {filter} />
<Feed skipCache {shouldDisplay} relays={[$relay.url]} {filter} />
{/if}

View File

@ -21,7 +21,7 @@ export const markAsSeenPublicly = batch(5000, async idChunks => {
const event = await signer.get().signAsUser(createReadReceipt(ids))
if (event) {
Publisher.publish({event, relays: hints.Outbox().getUrls()})
Publisher.publish({event, relays: hints.WriteRelays().getUrls()})
}
}
})
@ -41,7 +41,7 @@ export const markAsSeenPrivately = batch(5000, async idChunks => {
Publisher.publish({
event: rumor.wrap,
relays: hints.Outbox().getUrls(),
relays: hints.WriteRelays().getUrls(),
})
}
})

View File

@ -1,4 +1,5 @@
import {seconds} from "hurdak"
import {giftWrapKinds} from "src/util/nostr"
import {session, nip44, nip04} from "src/engine/session/derived"
import {hints} from "src/engine/relays/utils"
import {load} from "src/engine/network/utils"
@ -18,7 +19,7 @@ export const loadSeen = () => {
const since = Math.max(0, deletes_last_synced - seconds(6, "hour"))
return load({
relays: hints.Outbox().getUrls(),
relays: hints.WriteRelays().getUrls(),
filters: [{kinds: [15], authors: [pubkey], since}],
})
}
@ -40,7 +41,7 @@ export const loadGiftWrap = () => {
return load({
relays: hints.AllMessages().getUrls(),
filters: [{kinds: [1059, 1060], authors: [pubkey], since}],
filters: [{kinds: giftWrapKinds, authors: [pubkey], since}],
})
}
}

View File

@ -1,7 +1,7 @@
import {uniq, assoc, whereEq, sortBy, prop, without, mergeRight} from "ramda"
import {Tags, decodeAddress, getAddress} from "paravel"
import {switcherFn, batch} from "hurdak"
import {LOCAL_RELAY_URL, getPublicKey} from "src/util/nostr"
import {LOCAL_RELAY_URL, giftWrapKinds, getPublicKey} from "src/util/nostr"
import {projections} from "src/engine/core/projections"
import {updateStore} from "src/engine/core/commands"
import type {Event} from "src/engine/events/model"
@ -56,8 +56,8 @@ projections.addHandler(24, (e: Event) => {
relays: hints.scenario([relays]).getUrls(),
filters: [
...getIdFilters([address]),
{kinds: [1059, 1060], "#p": [pubkey]},
{kinds: [1059, 1060], authors: [pubkey]},
{kinds: giftWrapKinds, "#p": [pubkey]},
{kinds: giftWrapKinds, authors: [pubkey]},
],
})
} else {

View File

@ -1,7 +1,7 @@
import {now, decodeAddress, isGroupAddress} from "paravel"
import {seconds} from "hurdak"
import {partition} from "ramda"
import {noteKinds, repostKinds} from "src/util/nostr"
import {noteKinds, giftWrapKinds, repostKinds} from "src/util/nostr"
import {load} from "src/engine/network/utils"
import {hints} from "src/engine/relays/utils"
import {updateCurrentSession} from "src/engine/session/commands"
@ -55,7 +55,9 @@ export const loadGroupMessages = async (addresses = null) => {
const {admins, recipients, relays, since} = getGroupReqInfo(address)
const pubkeys = [...admins, ...recipients]
load({relays, filters: [{kinds: [1059, 1060], "#p": pubkeys, since}]})
if (pubkeys.length > 0) {
load({relays, filters: [{kinds: giftWrapKinds, "#p": pubkeys, since}]})
}
}
for (const address of communityAddrs) {
@ -68,7 +70,9 @@ export const loadGroupMessages = async (addresses = null) => {
updateCurrentSession($session => {
for (const address of addrs) {
$session.groups[address].last_synced = now()
if ($session.groups?.[address]) {
$session.groups[address].last_synced = now()
}
}
return $session

View File

@ -1,4 +1,4 @@
import {prop, uniqBy, defaultTo, sortBy, last, whereEq} from "ramda"
import {identity, prop, uniqBy, defaultTo, sortBy, last, whereEq} from "ramda"
import {ellipsize, seconds} from "hurdak"
import {Tags, decodeAddress, addressToNaddr} from "paravel"
import {fuzzy} from "src/util/misc"
@ -62,7 +62,7 @@ export const getGroupReqInfo = (address = null) => {
const admins = []
const addresses = []
const recipients = [pubkey.get()]
const recipients = [pubkey.get()].filter(identity)
for (const key of [...$groupSharedKeys, ...$groupAdminKeys]) {
const address = decodeAddress(key.group)

View File

@ -13,7 +13,7 @@ export const deriveHandlers = cached({
const $follows = follows.get()
load({
relays: hints.Inbox().getUrls(),
relays: hints.ReadRelays().getUrls(),
filters: [
{kinds: [31989], "#d": [String(kind)], authors: Array.from($follows)},
{kinds: [31990], "#k": [String(kind)]},

View File

@ -27,7 +27,7 @@ export const dvmRequest = async ({
onProgress = null,
}: DVMRequestOpts): Promise<Event> => {
if (!relays) {
relays = hints.merge([hints.Outbox(), hints.scenario([env.get().DVM_RELAYS])]).getUrls()
relays = hints.merge([hints.WriteRelays(), hints.scenario([env.get().DVM_RELAYS])]).getUrls()
}
if (typeof input !== "string") {

View File

@ -293,7 +293,7 @@ export class FeedLoader {
// If something has a parent id but we haven't found the parent yet, skip it until we have it.
const [ok, defer] = partition(e => this.parents.has(Tags.fromEvent(e).parent()?.value()), notes)
setTimeout(() => this.addToFeed(defer), 1500)
setTimeout(() => this.addToFeed(defer), 3000)
return ok
}
@ -305,7 +305,7 @@ export class FeedLoader {
const since = now() - guessFilterDelta(this.opts.filters)
const [defer, ok] = partition(e => e.created_at < since, notes)
setTimeout(() => this.addToFeed(defer), 4000)
setTimeout(() => this.addToFeed(defer), 5000)
return ok
}

View File

@ -176,7 +176,7 @@ export const getRelaysFromFilters = filters =>
return hints.FromPubkeys(shuffle(filter.authors))
}
return hints.Inbox()
return hints.ReadRelays()
}),
)
.getUrls()

View File

@ -7,7 +7,7 @@ export const publishNote = (content, tags = [], relays = null) =>
export const publishDeletion = ids =>
createAndPublish(5, {
relays: hints.Outbox().getUrls(),
relays: hints.WriteRelays().getUrls(),
tags: ids.map(id => [id.includes(":") ? "a" : "e", id]),
})

View File

@ -2,7 +2,7 @@ import {now, Tags} from "paravel"
import {seconds, batch, doPipe} from "hurdak"
import {pluck, max, slice, filter, without, sortBy} from "ramda"
import {updateIn} from "src/util/misc"
import {noteKinds, repostKinds, reactionKinds} from "src/util/nostr"
import {noteKinds, giftWrapKinds, repostKinds, reactionKinds} from "src/util/nostr"
import type {Event} from "src/engine/events/model"
import type {Filter} from "src/engine/network/model"
import {env} from "src/engine/session/state"
@ -58,7 +58,12 @@ const onNotificationEvent = batch(300, (chunk: Event[]) => {
})
export const getNotificationKinds = () =>
without(env.get().ENABLE_ZAPS ? [] : [9735], [...noteKinds, ...reactionKinds, 1059, 1060, 4])
without(env.get().ENABLE_ZAPS ? [] : [9735], [
...noteKinds,
...reactionKinds,
...giftWrapKinds,
4,
])
const getEventIds = (pubkey: string) =>
doPipe(events.get(), [
@ -86,7 +91,7 @@ export const loadNotifications = () => {
timeout: 15000,
skipCache: true,
closeOnEose: true,
relays: hints.Inbox().getUrls(),
relays: hints.ReadRelays().getUrls(),
onEvent: onNotificationEvent,
})
}
@ -101,7 +106,7 @@ export const listenForNotifications = async () => {
// Mentions
{kinds: noteKinds, "#p": [$session.pubkey], limit: 1, since},
// Messages/groups
{kinds: [4, 1059, 1060], "#p": [$session.pubkey], limit: 1, since},
{kinds: [4, ...giftWrapKinds], "#p": [$session.pubkey], limit: 1, since},
]
// Communities
@ -120,7 +125,7 @@ export const listenForNotifications = async () => {
filters,
timeout: 30_000,
skipCache: true,
relays: hints.Inbox().getUrls(),
relays: hints.ReadRelays().getUrls(),
onEvent: onNotificationEvent,
})
}

View File

@ -1,5 +1,5 @@
import {nip19} from "nostr-tools"
import {Router, RelayMode} from "paravel"
import {Router} from "paravel"
import {normalizeRelayUrl as normalize, ConnectionStatus, fromNostrURI} from "paravel"
import {sortBy, whereEq, pluck, uniq, prop, last} from "ramda"
import {displayList, switcher} from "hurdak"
@ -87,7 +87,7 @@ export const forcePlatformRelays = relays => {
const {PLATFORM_RELAYS} = env.get()
if (PLATFORM_RELAYS.length > 0) {
return PLATFORM_RELAYS
return Array.from(PLATFORM_RELAYS)
}
return relays
@ -97,17 +97,8 @@ export const hints = new Router({
getUserPubkey: () => stateKey.get(),
getGroupRelays: getGroupRelayUrls,
getCommunityRelays: getGroupRelayUrls,
getPubkeyRelays: (pubkey: string, mode: RelayMode = null) =>
getPubkeyRelayUrls(
pubkey,
switcher(mode, {
[RelayMode.Inbox]: "read",
[RelayMode.Outbox]: "write",
default: null,
}),
),
getDefaultRelays: () =>
getUserRelayUrls().concat(env.get().DEFAULT_RELAYS),
getPubkeyRelays: getPubkeyRelayUrls,
getDefaultRelays: () => getUserRelayUrls().concat(env.get().DEFAULT_RELAYS),
getDefaultLimit: () => parseInt(getSetting("relay_limit")),
getRelayQuality: (url: string) => {
const connection = pool.get(url, {autoConnect: false})

View File

@ -7,6 +7,6 @@ import {Publisher} from "src/engine/network/utils"
// Use an ephemeral private key for user privacy
export const publishReport = async (content = "", tags = []) =>
Publisher.publish({
relays: hints.Outbox().getUrls(),
relays: hints.WriteRelays().getUrls(),
event: await signer.get().signWithKey(createEvent(1984, {content, tags}), generatePrivateKey()),
})

View File

@ -7,12 +7,12 @@
</script>
<div class="relative flex items-center justify-between overflow-auto pb-px pt-1">
<div class="absolute bottom-px left-0 right-0 h-px w-full bg-neutral-600" />
<div class="absolute bottom-px left-0 right-0 h-px w-full bg-neutral-700" />
<div class="flex">
{#each tabs as tab}
<button
class="relative flex cursor-pointer items-end gap-2 border-b border-solid px-8 pb-4 transition-colors hover:border-neutral-500"
class:border-transparent={activeTab !== tab}
class:border-neutral-700={activeTab !== tab}
class:border-neutral-500={activeTab === tab}
on:click|preventDefault={() => setActiveTab(tab)}>
<slot name="tab" {tab}>{toTitle(tab)}</slot>

View File

@ -28,6 +28,7 @@ export const noteKinds = [1, 30023, 9802, 1808, 32123, 31923, 30402]
export const personKinds = [0, 2, 3, 10000, 10002]
export const reactionKinds = [7, 9735]
export const repostKinds = [6, 16]
export const giftWrapKinds = [1059, 1060]
export const userKinds = [...personKinds, 30001, 30003, 30078, 10004]
export const LOCAL_RELAY_URL = "local://coracle.relay"
@ -113,7 +114,7 @@ export const getContentWarning = e => {
return tags.topics().find(t => WARN_TAGS.has(t.toLowerCase()))
}
export const isGiftWrap = e => [1059, 1060].includes(e.kind)
export const isGiftWrap = e => giftWrapKinds.includes(e.kind)
export const parseAnything = async entity => {
entity = fromNostrURI(entity)