mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-29 16:31:04 +00:00
Guess delta from filter, don't duplicate session across multiple stores
This commit is contained in:
parent
66fcd2cc34
commit
c313069bc0
@ -6,21 +6,21 @@
|
||||
import Card from "src/partials/Card.svelte"
|
||||
import PersonCircle from "src/app/shared/PersonCircle.svelte"
|
||||
import {slowConnections} from "src/app/state"
|
||||
import {env, session, sessions, logoutPubkey, displayPubkey} from "src/engine2"
|
||||
import {env, pubkey, sessions, logoutPubkey, displayPubkey} from "src/engine2"
|
||||
|
||||
const showLogin = () => modal.push({type: "login/advanced"})
|
||||
</script>
|
||||
|
||||
<Popover theme="transparent" placement="top-end" opts={{hideOnClick: true}}>
|
||||
<div slot="trigger" class="relative flex cursor-pointer items-center">
|
||||
<PersonCircle size={10} pubkey={$session.pubkey} />
|
||||
<PersonCircle size={10} pubkey={$pubkey} />
|
||||
</div>
|
||||
<div slot="tooltip" class="flex justify-end">
|
||||
<Card class="mt-1 w-48 overflow-hidden shadow-lg">
|
||||
<div class="-mx-3 -mt-1">
|
||||
<Anchor
|
||||
class="block p-3 px-4 transition-all hover:bg-accent hover:text-white"
|
||||
href={`/${nip19.npubEncode($session.pubkey)}`}>
|
||||
href={`/${nip19.npubEncode($pubkey)}`}>
|
||||
<i class="fa fa-user mr-2" /> Profile
|
||||
</Anchor>
|
||||
<Anchor class="block p-3 px-4 transition-all hover:bg-accent hover:text-white" href="/keys">
|
||||
@ -49,11 +49,11 @@
|
||||
</Anchor>
|
||||
<div class="my-2 h-px w-full bg-gray-5" />
|
||||
{#each Object.values($sessions) as s (s.pubkey)}
|
||||
{#if s.pubkey !== $session.pubkey}
|
||||
{#if s.pubkey !== $pubkey}
|
||||
<div
|
||||
class="block flex cursor-pointer items-center justify-between gap-2 p-3 px-4
|
||||
transition-all hover:bg-accent hover:text-white"
|
||||
on:click={() => session.set(s)}>
|
||||
on:click={() => pubkey.set(s.pubkey)}>
|
||||
<div class="flex items-center gap-2">
|
||||
<PersonCircle pubkey={s.pubkey} />
|
||||
{displayPubkey(s.pubkey)}
|
||||
|
@ -21,7 +21,6 @@
|
||||
export let hideControls = false
|
||||
export let queryCache = false
|
||||
export let onEvent = null
|
||||
export let delta = null
|
||||
|
||||
let scroller, feed, scrollerElement
|
||||
let feedRelay = null
|
||||
@ -90,7 +89,6 @@
|
||||
filters: [compileFilter(filter)],
|
||||
shouldLoadParents: true,
|
||||
onEvent,
|
||||
delta,
|
||||
})
|
||||
|
||||
oldNotes = feed.feed
|
||||
|
@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import {seconds} from "hurdak"
|
||||
import Feed from "src/app/shared/Feed.svelte"
|
||||
|
||||
export let pubkey
|
||||
@ -8,4 +7,4 @@
|
||||
const filter = {kinds: [7], authors: [pubkey]}
|
||||
</script>
|
||||
|
||||
<Feed hideControls delta={seconds(12, "hour")} {relays} {filter} />
|
||||
<Feed hideControls {relays} {filter} />
|
||||
|
@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import {seconds} from "hurdak"
|
||||
import {noteKinds} from "src/util/nostr"
|
||||
import Feed from "src/app/shared/Feed.svelte"
|
||||
import {sessions} from "src/engine2/state"
|
||||
@ -10,9 +9,4 @@
|
||||
const filter = {kinds: noteKinds, authors: [pubkey]}
|
||||
</script>
|
||||
|
||||
<Feed
|
||||
invertColors
|
||||
delta={seconds(12, "hour")}
|
||||
queryCache={Boolean($sessions[pubkey])}
|
||||
{relays}
|
||||
{filter} />
|
||||
<Feed invertColors queryCache={Boolean($sessions[pubkey])} {relays} {filter} />
|
||||
|
@ -12,12 +12,12 @@
|
||||
import NoteById from "src/app/shared/NoteById.svelte"
|
||||
import PersonBadgeSmall from "src/app/shared/PersonBadgeSmall.svelte"
|
||||
import {
|
||||
session,
|
||||
getPubkeysWithDefaults,
|
||||
labels,
|
||||
getPubkeyHints,
|
||||
session,
|
||||
follows,
|
||||
subscribe,
|
||||
getPubkeyHints,
|
||||
getPubkeysWithDefaults,
|
||||
} from "src/engine2"
|
||||
|
||||
type LabelGroup = {
|
||||
|
@ -2,16 +2,14 @@
|
||||
import Feed from "src/app/shared/Feed.svelte"
|
||||
import Content from "src/partials/Content.svelte"
|
||||
import Heading from "src/partials/Heading.svelte"
|
||||
import {selectHints, getSetting} from "src/engine2"
|
||||
import {selectHints} from "src/engine2"
|
||||
|
||||
export let label
|
||||
export let hints
|
||||
export let ids
|
||||
|
||||
const relays = selectHints(getSetting("relay_limit"), hints)
|
||||
</script>
|
||||
|
||||
<Content>
|
||||
<Heading>{label}</Heading>
|
||||
<Feed invertColors {relays} filter={{ids}} />
|
||||
<Feed invertColors relays={selectHints(hints)} filter={{ids}} />
|
||||
</Content>
|
||||
|
@ -3,7 +3,7 @@
|
||||
import {onMount} from "svelte"
|
||||
import {fly} from "src/util/transition"
|
||||
import {navigate} from "svelte-routing"
|
||||
import {now, createScroller, formatTimestampAsLocalISODate} from "src/util/misc"
|
||||
import {now, createScroller, formatTimestampAsDate} from "src/util/misc"
|
||||
import {noteKinds, reactionKinds} from "src/util/nostr"
|
||||
import Tabs from "src/partials/Tabs.svelte"
|
||||
import Content from "src/partials/Content.svelte"
|
||||
@ -28,11 +28,8 @@
|
||||
const cur = tabNotifications[i]
|
||||
const prev = tabNotifications[i - 1]
|
||||
|
||||
if (
|
||||
!prev ||
|
||||
formatTimestampAsLocalISODate(prev.timestamp) !== formatTimestampAsLocalISODate(cur.timestamp)
|
||||
) {
|
||||
return formatTimestampAsLocalISODate(cur.timestamp)
|
||||
if (!prev || formatTimestampAsDate(prev.timestamp) !== formatTimestampAsDate(cur.timestamp)) {
|
||||
return formatTimestampAsDate(cur.timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
import {appDataKeys} from "src/util/nostr"
|
||||
import {session} from "src/engine2/state"
|
||||
import {canSign, nip04} from "src/engine2/queries"
|
||||
import {session, canSign, nip04} from "src/engine2/queries"
|
||||
import {publishEvent} from "./util"
|
||||
|
||||
export const setAppData = async (d: string, data: any) => {
|
||||
|
@ -1,9 +1,9 @@
|
||||
import EventEmitter from "events"
|
||||
import {omit} from "ramda"
|
||||
import {defer, union, difference} from "hurdak"
|
||||
import {info} from "src/util/logger"
|
||||
import type {Event, NostrEvent} from "src/engine2/model"
|
||||
import {getUrls, getExecutor} from "src/engine2/queries"
|
||||
import {projections} from "src/engine2/projections"
|
||||
|
||||
export type PublisherOpts = {
|
||||
timeout?: number
|
||||
@ -17,13 +17,16 @@ export type StaticPublisherOpts = PublisherOpts & {
|
||||
|
||||
export class Publisher extends EventEmitter {
|
||||
result = defer()
|
||||
event: NostrEvent
|
||||
|
||||
constructor(readonly event: NostrEvent) {
|
||||
constructor(event: NostrEvent) {
|
||||
super()
|
||||
|
||||
if ((event as Event).wrap) {
|
||||
throw new Error("Can't publish unwrapped events")
|
||||
}
|
||||
|
||||
this.event = event
|
||||
}
|
||||
|
||||
static publish({event, relays, ...opts}: StaticPublisherOpts) {
|
||||
@ -63,6 +66,8 @@ export class Publisher extends EventEmitter {
|
||||
this.emit("progress", progress)
|
||||
}
|
||||
|
||||
projections.push({...this.event, seen_on: []})
|
||||
|
||||
setTimeout(() => {
|
||||
for (const url of urls) {
|
||||
if (!succeeded.has(url) && !failed.has(url)) {
|
||||
@ -73,7 +78,7 @@ export class Publisher extends EventEmitter {
|
||||
attemptToResolve()
|
||||
}, timeout)
|
||||
|
||||
const sub = executor.publish(omit(["seen_on"], this.event), {
|
||||
const sub = executor.publish(this.event, {
|
||||
verb,
|
||||
onOk: (url: string) => {
|
||||
succeeded.add(url)
|
||||
|
@ -1,13 +1,13 @@
|
||||
import {omit, assoc} from "ramda"
|
||||
import {generatePrivateKey, getPublicKey} from "nostr-tools"
|
||||
import type {Session} from "src/engine2/model"
|
||||
import {pool, sessions, session} from "src/engine2/state"
|
||||
import {canSign, signer} from "src/engine2/queries"
|
||||
import {pool, sessions, pubkey} from "src/engine2/state"
|
||||
import {canSign, signer, session} from "src/engine2/queries"
|
||||
import {buildEvent} from "./util"
|
||||
|
||||
const addSession = (s: Session) => {
|
||||
sessions.update(assoc(s.pubkey, s))
|
||||
session.set(s)
|
||||
pubkey.set(s.pubkey)
|
||||
}
|
||||
|
||||
export const loginWithPrivateKey = privkey =>
|
||||
@ -29,7 +29,7 @@ export const logoutPubkey = pubkey => {
|
||||
}
|
||||
|
||||
export const logout = () => {
|
||||
session.set(null)
|
||||
pubkey.set(null)
|
||||
sessions.set({})
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,6 @@ projections.addHandler(30078, async (e: Event) => {
|
||||
}
|
||||
|
||||
if (Tags.from(e).getMeta("d") === appDataKeys.NIP28_LAST_CHECKED) {
|
||||
console.log(e)
|
||||
await tryJson(async () => {
|
||||
const payload = JSON.parse(await nip04.get().decryptAsUser(e.content, e.pubkey))
|
||||
|
||||
|
@ -2,8 +2,8 @@ import {find, whereEq, nth} from "ramda"
|
||||
import {derived} from "src/engine2/util"
|
||||
import type {Event} from "src/engine2/model"
|
||||
import {findReplyAndRootIds} from "src/util/nostr"
|
||||
import {session, lists} from "src/engine2/state"
|
||||
import {user} from "src/engine2/queries/session"
|
||||
import {lists} from "src/engine2/state"
|
||||
import {user, session} from "src/engine2/queries/session"
|
||||
|
||||
export const mutes = user.derived($user => ($user?.mutes || []).map(nth(1)))
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import {prop} from "ramda"
|
||||
import {env, session} from "src/engine2/state"
|
||||
import {env} from "src/engine2/state"
|
||||
import {session} from "src/engine2/queries"
|
||||
|
||||
export const getDefaultSettings = () => ({
|
||||
relay_limit: 10,
|
||||
|
@ -2,12 +2,16 @@ import {max, sortBy} from "ramda"
|
||||
import {Tags, findReplyId, findReplyAndRootIds} from "src/util/nostr"
|
||||
import {formatTimestampAsLocalISODate, tryJson} from "src/util/misc"
|
||||
import {derived} from "src/engine2/util/store"
|
||||
import {session, events, notificationsLastChecked} from "src/engine2/state"
|
||||
import {userEventsById} from "src/engine2/queries/session"
|
||||
import {events, notificationsLastChecked} from "src/engine2/state"
|
||||
import {session, userEventsById} from "src/engine2/queries/session"
|
||||
|
||||
export const notifications = derived(
|
||||
[session, userEventsById.throttle(500), events.throttle(500)],
|
||||
([$session, $userEventsById, $events]) => {
|
||||
if (!$session) {
|
||||
return []
|
||||
}
|
||||
|
||||
return $events.filter(e => {
|
||||
const {root, reply} = findReplyAndRootIds(e)
|
||||
|
||||
|
@ -2,7 +2,7 @@ import {nip19} from "nostr-tools"
|
||||
import {propEq} from "ramda"
|
||||
import {createMap} from "hurdak"
|
||||
import {derived} from "src/engine2/util/store"
|
||||
import {session, events, people} from "src/engine2/state"
|
||||
import {sessions, pubkey, events, people} from "src/engine2/state"
|
||||
import {prepareNdk, ndkInstances} from "./ndk"
|
||||
import {Signer} from "./signer"
|
||||
import {Nip04} from "./nip04"
|
||||
@ -21,7 +21,9 @@ export const isKeyValid = (key: string) => {
|
||||
return true
|
||||
}
|
||||
|
||||
export const stateKey = session.derived($s => $s?.pubkey || "anonymous")
|
||||
export const stateKey = pubkey.derived($pk => $pk || "anonymous")
|
||||
|
||||
export const session = derived([pubkey, sessions], ([$pk, $sessions]) => $sessions[$pk])
|
||||
|
||||
export const user = derived([session, people.mapStore], ([$s, $p]) => $p.get($s?.pubkey))
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
import {mergeRight, identity, sortBy} from "ramda"
|
||||
import {seconds, first} from "hurdak"
|
||||
import {first} from "hurdak"
|
||||
import {now} from "src/util/misc"
|
||||
import {EPOCH} from "src/util/nostr"
|
||||
import type {Filter, Event} from "src/engine2/model"
|
||||
import type {Subscription} from "./subscription"
|
||||
import {subscribe} from "./subscription"
|
||||
import {guessFilterDelta} from "./filter"
|
||||
|
||||
export type CursorOpts = {
|
||||
relay: string
|
||||
filters: Filter[]
|
||||
onEvent?: (e: Event) => void
|
||||
delta?: number
|
||||
}
|
||||
|
||||
export class Cursor {
|
||||
@ -23,7 +23,7 @@ export class Cursor {
|
||||
done = false
|
||||
|
||||
constructor(readonly opts: CursorOpts) {
|
||||
this.delta = opts.delta || seconds(10, "minute")
|
||||
this.delta = guessFilterDelta(opts.filters)
|
||||
this.since = now() - this.delta
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,6 @@ export type FeedOpts = {
|
||||
depth: number
|
||||
relays: string[]
|
||||
filters: Filter[]
|
||||
delta?: number
|
||||
onEvent?: (e: Event) => void
|
||||
shouldLoadParents?: boolean
|
||||
}
|
||||
@ -61,7 +60,6 @@ export class FeedLoader {
|
||||
relay =>
|
||||
new Cursor({
|
||||
relay,
|
||||
delta: opts.delta,
|
||||
filters: opts.filters,
|
||||
onEvent: batch(100, (context: Event[]) => {
|
||||
this.context.addContext(context, {shouldLoadParents: true, depth: opts.depth})
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {omit, prop, groupBy, uniq} from "ramda"
|
||||
import {shuffle} from "hurdak"
|
||||
import {omit, find, prop, groupBy, uniq} from "ramda"
|
||||
import {shuffle, seconds, avg} from "hurdak"
|
||||
import type {DynamicFilter, Filter} from "src/engine2/model"
|
||||
import {env} from "src/engine2/state"
|
||||
import {follows, network} from "src/engine2/queries"
|
||||
@ -57,6 +57,30 @@ export const getIdFilters = values => {
|
||||
return filters
|
||||
}
|
||||
|
||||
export const getFilterGenerality = filter => {
|
||||
if (filter.ids) {
|
||||
return 1
|
||||
}
|
||||
|
||||
const hasTags = find(k => k.startsWith("#"), Object.keys(filter))
|
||||
|
||||
if (filter.pubkeys && hasTags) {
|
||||
return 0.8
|
||||
}
|
||||
|
||||
if (filter.pubkeys) {
|
||||
return 1 - Math.max(1, filter.pubkeys.length / 100)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
export const guessFilterDelta = filters => {
|
||||
const avgGenerality = avg(filters.map(getFilterGenerality))
|
||||
|
||||
return Math.round(seconds(7, "day") * Math.max(0.001, avgGenerality))
|
||||
}
|
||||
|
||||
export const getPubkeysWithDefaults = (pubkeys: string[]) =>
|
||||
shuffle(pubkeys.length > 0 ? pubkeys : (env.get().DEFAULT_FOLLOWS as string[])).slice(0, 1024)
|
||||
|
||||
|
@ -2,8 +2,8 @@ import {pluck} from "ramda"
|
||||
import {batch, seconds} from "hurdak"
|
||||
import {now} from "src/util/misc"
|
||||
import {EventKind} from "src/engine2/model"
|
||||
import {session, nip04ChannelsLastChecked} from "src/engine2/state"
|
||||
import {getInboxHints, getUserRelayUrls} from "src/engine2/queries"
|
||||
import {nip04ChannelsLastChecked} from "src/engine2/state"
|
||||
import {session, getInboxHints, getUserRelayUrls} from "src/engine2/queries"
|
||||
import {load} from "./load"
|
||||
import {loadPubkeys} from "./pubkeys"
|
||||
import {subscribe} from "./subscription"
|
||||
|
@ -1,8 +1,8 @@
|
||||
import {seconds} from "hurdak"
|
||||
import {now} from "src/util/misc"
|
||||
import {EventKind} from "src/engine2/model"
|
||||
import {session, nip24ChannelsLastChecked} from "src/engine2/state"
|
||||
import {getUserRelayUrls, nip24Channels, getNip24ChannelPubkeys} from "src/engine2/queries"
|
||||
import {nip24ChannelsLastChecked} from "src/engine2/state"
|
||||
import {session, getUserRelayUrls, nip24Channels, getNip24ChannelPubkeys} from "src/engine2/queries"
|
||||
import {load} from "./load"
|
||||
import {loadPubkeys} from "./pubkeys"
|
||||
|
||||
|
@ -4,8 +4,8 @@ import type {Event, Delete, Session, Channel, Topic, List, Person, Relay} from "
|
||||
|
||||
// Synchronous stores
|
||||
|
||||
export const pubkey = writable<string | null>(null)
|
||||
export const sessions = writable<Record<string, Session>>({})
|
||||
export const session = writable<Session | null>(null)
|
||||
export const env = writable<Record<string, any>>({})
|
||||
export const notificationsLastChecked = writable(0)
|
||||
export const nip04ChannelsLastChecked = writable(0)
|
||||
|
@ -24,8 +24,8 @@ const sortByPubkeyWhitelist = (fallback: (x: any) => number) => (rows: Record<st
|
||||
}
|
||||
|
||||
export const storage = new Storage([
|
||||
new LocalStorageAdapter("pubkey", state.pubkey),
|
||||
new LocalStorageAdapter("sessions", state.sessions),
|
||||
new LocalStorageAdapter("session", state.session),
|
||||
new LocalStorageAdapter("notificationsLastChecked", state.notificationsLastChecked),
|
||||
new LocalStorageAdapter("nip04ChannelsLastChecked", state.nip04ChannelsLastChecked),
|
||||
new LocalStorageAdapter("nip24ChannelsLastChecked", state.nip24ChannelsLastChecked),
|
||||
|
@ -16,6 +16,12 @@
|
||||
"bg-input border border-solid border-gray-3 text-black",
|
||||
{"pl-10": showBefore, "pr-10": showAfter}
|
||||
)
|
||||
|
||||
$: {
|
||||
if ($$props.type === "range" && typeof value === "string") {
|
||||
value = parseInt(value)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class={cx(wrapperClass, "relative")}>
|
||||
|
Loading…
Reference in New Issue
Block a user