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 c6ffb56a..3e9fd068 100644
Binary files a/package-lock.json and b/package-lock.json differ
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}
-