From 9bdb707d272022960ad96fd3c32fdb0fcdda4e03 Mon Sep 17 00:00:00 2001 From: Jonathan Staab Date: Mon, 6 Feb 2023 10:41:48 -0600 Subject: [PATCH] Fix alerts --- .husky/pre-commit | 5 +++-- README.md | 13 +++++++++---- package-lock.json | Bin 288725 -> 343546 bytes package.json | 7 +++++-- src/App.svelte | 14 ++++++++++---- src/agent/pool.ts | 16 +++++++--------- src/app/alerts.js | 29 +++++++++++++++++++---------- src/app/index.ts | 30 +++++++++++++++++++----------- src/app/loaders.ts | 15 ++------------- src/partials/Compose.svelte | 2 +- src/partials/Like.svelte | 11 ++++++----- src/partials/Spinner.svelte | 4 +++- src/routes/Alerts.svelte | 31 +++++++++---------------------- 13 files changed, 93 insertions(+), 84 deletions(-) diff --git a/.husky/pre-commit b/.husky/pre-commit index 524f353b..b5588ea2 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,5 +1,6 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -npm run lint -npm run check +npm run qa:lint +npm run qa:check + diff --git a/README.md b/README.md index 669dd01e..3a87a446 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,6 @@ If you like Coracle and want to support its development, you can donate sats via - Put user detail in a modal? - ReplaceState for settings modals? - [ ] Mentions are sorta weird, usually mention self -- [ ] Alerts are not showing likes, just generally screwy. Maybe because I threadify before adding to the db? - [ ] Change network tab to list relays the user is connected to - [ ] Sync mentions box and in-reply mentions - [ ] Add petnames for channels @@ -63,11 +62,17 @@ If you like Coracle and want to support its development, you can donate sats via # Changelog +## 0.2.10 + +- [x] Fixed likes not showing up in alerts +- [x] Raised threshold for pool to 2 so we don't have such a small amount of results +- [x] Wait for profile info on login, navigate to network by default + ## 0.2.9 -- [x] Fix a bug in pool.subscribe which was causing requests to wait for all connections -- [x] Add typescript with pre-commit hook -- [x] Fix layout for chat, person pages +- [x] Fixed a bug in pool.subscribe which was causing requests to wait for all connections +- [x] Added typescript with pre-commit hook +- [x] Fixed layout for chat, person pages - [x] Parse relays for kind 3 ## 0.2.8 diff --git a/package-lock.json b/package-lock.json index c6ffb56a067450fdbfc275f2172e5b90c701a29e..3e9fd0683e91b2243792e345541b3ada295b20a0 100644 GIT binary patch delta 25751 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 delta 648 zcmW;I*-KOb6bE3=x#!-Q@s8r;Ad#)uGAfn$Fzr3~P$8Mc_#j4PI1jCpMo>hOA-GY| zFyW!h2r5M~($gjICsm=u0kB4@KXf@Wp?72VQzQ%2@5gG&_2OpTCLT zd$)t4)!%%jIJJd5208=OVtD#gwZ!MNFTs}>?j7MQ=urPU^))HnmQ8D4pH7aFvwo;6A;598p>vgIU z?ChjL3p=`L$cc(xI+}v1A!@X>rCi1$zbbr@505hR;5SOZoF9~9=(vk5*usT`Cl+TJ z$aZs{8w+M}P9l1IymJZK3wg7FwZ&ZTLHhwdY@_rz*O_{@mIbS8c+^7WIX+9+qLLqd#1TbeAj zhG~WlhsE2lk^EYDh&u5&MH-!WKSzS3y4Oh3J>BGul!g4dwVF(nq{~ObzpnL+RhbeK zU6d_T*q^HIM}ju=>yE0ZSP=1Hvs!GP>dMo&;i zT#=4_Cfdp+X6XGoaUfbNDTG(`5@0+(BLxXKaY52-oNkti*?R00C+Xcn{-vP;BUKAB z%(+66tk%bYl%q>ZM^x)uLL?#P2aFGEo?peA4$W)1_HO i;?;+Byb9xgWORXs=9|-)m2QqW(X`YITk!bJ?~cFce)*vQ diff --git a/package.json b/package.json index 4f5b0f30..5f3bd4b6 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,10 @@ "dev": "vite", "build": "vite build", "preview": "vite preview", - "lint": "eslint src/*/** --quiet", - "check": "svelte-check --tsconfig ./tsconfig.json --threshold error" + "qa:lint": "eslint src/*/** --quiet", + "qa:check": "svelte-check --tsconfig ./tsconfig.json --threshold error", + "qa:all": "run-p qa:lint qa:check", + "watch": "find src -type f | entr -r npm run qa:all" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^1.1.0", @@ -36,6 +38,7 @@ "hurdak": "github:ConsignCloud/hurdak", "husky": "^8.0.3", "nostr-tools": "^1.2.1", + "npm-run-all": "^4.1.5", "ramda": "^0.28.0", "svelte-check": "^3.0.3", "svelte-link-preview": "^0.3.3", diff --git a/src/App.svelte b/src/App.svelte index e0355f01..bdcae9a8 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -12,9 +12,10 @@ import {displayPerson, isLike} from 'src/util/nostr' import {timedelta, now} from 'src/util/misc' import {keys, user, pool, getRelays} from 'src/agent' - import {modal, toast, settings, logUsage, alerts, messages} from "src/app" + import {modal, toast, settings, logUsage, alerts, messages, loadAppData} from "src/app" import {routes} from "src/app/ui" import Anchor from 'src/partials/Anchor.svelte' + import Content from 'src/partials/Content.svelte' import Spinner from 'src/partials/Spinner.svelte' import Modal from 'src/partials/Modal.svelte' import SignUp from "src/views/SignUp.svelte" @@ -74,9 +75,7 @@ onMount(() => { if ($user) { - alerts.load(getRelays(), $user.pubkey) - alerts.listen(getRelays(), $user.pubkey) - messages.listen(getRelays(), $user.pubkey) + loadAppData($user.pubkey) } const interval = setInterval(() => { @@ -301,6 +300,13 @@ {:else if $modal.type === 'person/settings'} + {:else if $modal.type === 'message'} + +
{$modal.message}
+ {#if $modal.spinner} + + {/if} +
{/if} {/if} diff --git a/src/agent/pool.ts b/src/agent/pool.ts index dfa45b1f..89e1c3e9 100644 --- a/src/agent/pool.ts +++ b/src/agent/pool.ts @@ -192,17 +192,15 @@ const request = (relays, filters, {threshold = 2} = {}): Promise { - const done = ( - eose.length === relays.length - || eose.filter(url => relaysWithEvents.has(url)).length >= threshold - || ( - Date.now() - now >= 1000 - && eose.length > relays.length - Math.round(relays.length / 10) - ) - || Date.now() - now >= 5000 + const allEose = eose.length === relays.length + const atThreshold = eose.filter(url => relaysWithEvents.has(url)).length >= threshold + const hardTimeout = Date.now() - now >= 5000 + const softTimeout = ( + Date.now() - now >= 1000 + && eose.length > relays.length - Math.round(relays.length / 10) ) - if (done) { + if (allEose || atThreshold || hardTimeout || softTimeout) { agg.unsub() resolve(events) } diff --git a/src/app/alerts.js b/src/app/alerts.js index fe98c6fd..9c1d32d7 100644 --- a/src/app/alerts.js +++ b/src/app/alerts.js @@ -1,9 +1,10 @@ import {get} from 'svelte/store' -import {synced, batch, now} from 'src/util/misc' -import {isAlert} from 'src/util/nostr' -import {load as _load, listen as _listen, getMuffle, db} from 'src/agent' +import {groupBy, pluck, partition, propEq} from 'ramda' +import {synced, timedelta, batch, now} from 'src/util/misc' +import {isAlert, findReplyId} from 'src/util/nostr' +import {load as _load, listen as _listen, db} from 'src/agent' import loaders from 'src/app/loaders' -import {threadify} from 'src/app' +import {annotate} from 'src/app' let listener @@ -14,21 +15,29 @@ const onChunk = async (relays, pubkey, events) => { events = events.filter(e => isAlert(e, pubkey)) if (events.length > 0) { - const context = await loaders.loadContext(relays, events, {threshold: 2}) - const notes = threadify(events, context, {muffle: getMuffle()}) + const context = await loaders.loadContext(relays, events) + const [likes, notes] = partition(propEq('kind', 7), events) + const annotatedNotes = notes.map(n => annotate(n, context)) + const likesByParent = groupBy(findReplyId, likes) + const likedNotes = context + .filter(e => likesByParent[e.id]) + .map(e => annotate({...e, likedBy: pluck('pubkey', likesByParent[e.id])}, context)) - await db.table('alerts').bulkPut(notes) + await db.table('alerts').bulkPut(annotatedNotes.concat(likedNotes)) mostRecentAlert.update($t => events.reduce((t, e) => Math.max(t, e.created_at), $t)) } } const load = async (relays, pubkey) => { - const since = get(mostRecentAlert) + // Include an offset so we don't miss alerts on one relay but not another + const since = get(mostRecentAlert) - timedelta(30, 'days') + + // Crank the threshold up since we can afford for this to be slow const events = await _load( relays, - {kinds: [1, 7], '#p': [pubkey], since, limit: 100}, - {threshold: 2} + {kinds: [1, 7], '#p': [pubkey], since, limit: 1000}, + {threshold: 10} ) onChunk(relays, pubkey, events) diff --git a/src/app/index.ts b/src/app/index.ts index b07798de..55707c18 100644 --- a/src/app/index.ts +++ b/src/app/index.ts @@ -14,6 +14,15 @@ import loaders from 'src/app/loaders' export {toast, modal, settings, alerts, messages, logUsage} +export const loadAppData = pubkey => { + return Promise.all([ + loaders.loadNetwork(getRelays(), pubkey), + alerts.load(getRelays(), pubkey), + alerts.listen(getRelays(), pubkey), + messages.listen(getRelays(), pubkey), + ]) +} + export const login = async ({privkey, pubkey}: {privkey?: string, pubkey?: string}, usingExtension = false) => { if (privkey) { keys.setPrivateKey(privkey) @@ -21,16 +30,18 @@ export const login = async ({privkey, pubkey}: {privkey?: string, pubkey?: strin keys.setPublicKey(pubkey) } + modal.set({type: 'message', message: "Loading your profile data...", spinner: true}) + // Load network and start listening, but don't wait for it - loaders.loadNetwork(getRelays(), pubkey), - alerts.load(getRelays(), pubkey), - alerts.listen(getRelays(), pubkey), - messages.listen(getRelays(), pubkey) + loadAppData(pubkey) + + // Load our user so we can populate network and show profile info + await loaders.loadPeople(getRelays(), [pubkey]) // Not ideal, but the network tab depends on the user's social network being // loaded, so put them on global when they first log in so we're not slowing // down users' first run experience too much - navigate('/notes/global') + navigate('/notes/network') } export const addRelay = async relay => { @@ -46,12 +57,8 @@ export const addRelay = async relay => { // Publish to the new set of relays await cmd.setRelays(relays, relays) - await Promise.all([ - loaders.loadNetwork(relays, person.pubkey), - alerts.load(relays, person.pubkey), - alerts.listen(relays, person.pubkey), - messages.listen(getRelays(), person.pubkey) - ]) + // Reload alerts, messages, etc + await loadAppData(person.pubkey) } } @@ -126,6 +133,7 @@ export const annotate = (note, context) => { export const threadify = (events, context, {muffle = [], showReplies = true} = {}) => { const contextById = createMap('id', events.concat(context)) + // Show parents when possible. For reactions, if there's no parent, // throw it away. Sort by created date descending const notes = sortBy( diff --git a/src/app/loaders.ts b/src/app/loaders.ts index 7a98dcbb..bbcc811b 100644 --- a/src/app/loaders.ts +++ b/src/app/loaders.ts @@ -2,8 +2,7 @@ import {uniqBy, prop, uniq, flatten, pluck, identity} from 'ramda' import {ensurePlural, createMap, chunk} from 'hurdak/lib/hurdak' import {findReply, personKinds, Tags} from 'src/util/nostr' import {now, timedelta} from 'src/util/misc' -import {load, getPerson} from 'src/agent' -import defaults from 'src/agent/defaults' +import {load, getPerson, getFollows} from 'src/agent' const getStalePubkeys = pubkeys => { // If we're not reloading, only get pubkeys we don't already know about @@ -28,17 +27,7 @@ const loadPeople = (relays, pubkeys, {kinds = personKinds, force = false, ...opt } const loadNetwork = async (relays, pubkey) => { - // Get this user's profile to start with. This may update what relays - // are available, so don't assign relays to a variable here. - const events = pubkey ? await loadPeople(relays, [pubkey], {force: true}) : [] - let petnames = Tags.from(events.filter(e => e.kind === 3)).type("p").all() - - // Default to some cool guys we know - if (petnames.length === 0) { - petnames = defaults.petnames - } - - const tags = Tags.wrap(petnames) + const tags = Tags.wrap(getFollows(pubkey)) // Use nip-2 recommended relays to load our user's second-order follows await loadPeople(tags.relays(), tags.values().all()) diff --git a/src/partials/Compose.svelte b/src/partials/Compose.svelte index 3c0a28be..a7a78f0b 100644 --- a/src/partials/Compose.svelte +++ b/src/partials/Compose.svelte @@ -178,7 +178,7 @@ {#if suggestions.length > 0} -
+
{#each suggestions as person, i (person.pubkey)} {#if isOpen} {/if} diff --git a/src/partials/Spinner.svelte b/src/partials/Spinner.svelte index 8c2017b9..c3386213 100644 --- a/src/partials/Spinner.svelte +++ b/src/partials/Spinner.svelte @@ -1,9 +1,11 @@ -
+
diff --git a/src/routes/Alerts.svelte b/src/routes/Alerts.svelte index bc0b6fe4..618daa1a 100644 --- a/src/routes/Alerts.svelte +++ b/src/routes/Alerts.svelte @@ -3,14 +3,14 @@ import {onMount} from 'svelte' import {fly} from 'svelte/transition' import {now, createScroller} from 'src/util/misc' - import {user, db} from 'src/agent' + import {db} from 'src/agent' import {alerts} from 'src/app' import Note from 'src/partials/Note.svelte' import Content from 'src/partials/Content.svelte' import Like from 'src/partials/Like.svelte' let limit = 0 - let annotatedNotes = [] + let notes = [] onMount(async () => { alerts.lastCheckedAlerts.set(now()) @@ -19,37 +19,24 @@ limit += 10 const events = await db.table('alerts').toArray() - const notes = events.filter(e => e.kind === 1) - const likes = events.filter(e => e.kind === 7) - // Combine likes of a single note. Remove grandchild likes - const likesById = {} - for (const like of likes.filter(e => e.parent?.pubkey === $user.pubkey)) { - if (!likesById[like.parent.id]) { - likesById[like.parent.id] = {...like.parent, people: []} - } - - likesById[like.parent.id].people.push(like.person) - } - - annotatedNotes = sortBy( - e => -e.created_at, - notes - .filter(e => e && e.pubkey !== $user.pubkey) - .concat(Object.values(likesById)) - ).slice(0, limit) + notes = sortBy(e => -e.created_at, events).slice(0, limit) }) }) - {#each annotatedNotes as e (e.id)} + {#each notes as e (e.id)}
- {#if e.people} + {#if e.likedBy} {:else} {/if}
+ {:else} + + No alerts found - check back later! + {/each}