From a8efa9ffc2905b42efcf1cb83352dd6a23c2c9df Mon Sep 17 00:00:00 2001 From: Jonathan Staab Date: Tue, 7 Feb 2023 14:24:13 -0600 Subject: [PATCH] Re-design relays page and person relays list with metadata --- .eslintrc.cjs | 4 +- .husky/pre-commit | 3 +- README.md | 21 ++++++-- package.json | 6 +-- src/App.svelte | 40 ++++++++++++-- src/app/index.ts | 2 +- src/partials/RelayCard.svelte | 87 ++++++++++++++++++++++++++++++ src/routes/Login.svelte | 2 +- src/routes/RelayList.svelte | 94 +++++++++------------------------ src/views/NoteCreate.svelte | 2 +- src/views/person/Network.svelte | 23 ++------ 11 files changed, 181 insertions(+), 103 deletions(-) create mode 100644 src/partials/RelayCard.svelte diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 79a6a723..34646ad6 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -25,8 +25,10 @@ module.exports = { }, rules: { "a11y-click-events-have-key-events": "off", + "a11y-autofocus": "off", "no-unused-vars": ["error", {args: "none"}], "no-async-promise-executor": "off", + "@typescript-eslint/no-explicit-any": "off", }, - ignorePatterns: ["*.svg"] + ignorePatterns: ["*.svg"], } diff --git a/.husky/pre-commit b/.husky/pre-commit index b5588ea2..3c39d1f8 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,6 +1,5 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -npm run qa:lint -npm run qa:check +npm run check diff --git a/README.md b/README.md index 8561ead6..7c15cec4 100644 --- a/README.md +++ b/README.md @@ -34,9 +34,12 @@ If you like Coracle and want to support its development, you can donate sats via # Missions - [ ] Image uploads - - Use dufflepud. Default will charge via lightning and have a tos, others can self-host and skip that. + - Default will charge via lightning and have a tos, others can self-host and skip that. - Add banner field to profile -- [ ] Allow users to select which relay they're reading from, allow more advanced custom feeds ala tweetdeck + - Linode/Digital Ocean + - https://github.com/brandonsavage/Upload + - https://github.com/seaweedfs/seaweedfs + - https://github.com/cubefs/cubefs - [ ] Add relay selector when publishing a note - [ ] Support invoices, tips, zaps https://twitter.com/jb55/status/1604131336247476224 - [ ] Separate settings for read, write, and broadcast relays based on NIP 65 @@ -53,9 +56,21 @@ If you like Coracle and want to support its development, you can donate sats via - https://github.com/nostr-protocol/nips/pull/205#issuecomment-1419234230 - [ ] Change network tab to list relays the user is connected to - [ ] Sync mentions box and in-reply mentions -- [ ] Add petnames for channels +- [ ] Channels + - [ ] Ability to leave/mute DM conversation + - [ ] Add petnames for channels - [ ] Add notifications for chat messages +# Current + +- [x] Re-design relays page and person relays list with metadata +- [ ] Add relay selection to new note screen +- [ ] Add relay selection to reply widget +- [ ] Make feeds page customizable. This could potentially use the "lists" NIP +- [ ] Show notification at top of feeds: "Showing notes from 3 relays". Click to customize. +- [ ] Click through on relays page to view a feed for only that relay. +- [ ] Custom views: slider between fast/complete with a warning at either extreme + # Changelog ## 0.2.10 diff --git a/package.json b/package.json index 18fa9688..9272e1b6 100644 --- a/package.json +++ b/package.json @@ -7,9 +7,9 @@ "dev": "vite", "build": "vite build", "preview": "vite preview", - "qa:lint": "eslint src/*/** --quiet", - "qa:check": "svelte-check --tsconfig ./tsconfig.json --threshold error", - "qa:all": "run-p qa:lint qa:check", + "check:es": "eslint src/*/** --quiet", + "check:ts": "svelte-check --tsconfig ./tsconfig.json --threshold error", + "check": "run-p check:*", "watch": "find src -type f | entr -r" }, "devDependencies": { diff --git a/src/App.svelte b/src/App.svelte index a5fffa24..0107130a 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -10,8 +10,8 @@ import {Router, Route, links, navigate} from "svelte-routing" import {globalHistory} from "svelte-routing/src/history" import {displayPerson, isLike} from 'src/util/nostr' - import {timedelta, now, sleep} from 'src/util/misc' - import {keys, user, pool, getRelays} from 'src/agent' + import {timedelta, shuffle, now, sleep} from 'src/util/misc' + import {db, keys, user, pool, getRelays} from 'src/agent' import {modal, toast, settings, logUsage, alerts, messages, loadAppData} from "src/app" import {routes} from "src/app/ui" import Anchor from 'src/partials/Anchor.svelte' @@ -82,7 +82,14 @@ loadAppData($user.pubkey) } + // Background work + const interval = setInterval(() => { + alertSlowConnections() + retrieveRelayMeta() + }, 2_000) + + const alertSlowConnections = () => { // Only notify about relays the user is actually subscribed to const relayUrls = pluck('url', getRelays()) @@ -101,7 +108,34 @@ // Alert the user to any heinously slow connections slowConnections = pool.getConnections() .filter(({url, stats: s}) => relayUrls.includes(url) && s.timer / s.count > 3000) - }, 10_000) + } + + const retrieveRelayMeta = async () => { + const {dufflepudUrl} = $settings + + // Find relays with old/missing metadata and refresh them. Only pick a + // few so we're not sending too many concurrent http requests + const allRelays = await db.table('relays').toArray() + const staleRelays = allRelays + .filter(r => (r.refreshed_at || 0) < now() - timedelta(7, 'days')) + const staleRelaysSample = shuffle(staleRelays).slice(0, 10) + + const freshRelays = await Promise.all( + staleRelaysSample.map(async ({url}) => { + const res = await fetch(dufflepudUrl + '/relay/info', { + method: 'POST', + body: JSON.stringify({url}), + headers: { + 'Content-Type': 'application/json', + }, + }) + + return {...await res.json(), url, refreshed_at: now()} + }) + ) + + db.table('relays').bulkPut(freshRelays) + } // Close menu on click outside document.querySelector("html").addEventListener("click", e => { diff --git a/src/app/index.ts b/src/app/index.ts index 55707c18..336b01f7 100644 --- a/src/app/index.ts +++ b/src/app/index.ts @@ -23,7 +23,7 @@ export const loadAppData = pubkey => { ]) } -export const login = async ({privkey, pubkey}: {privkey?: string, pubkey?: string}, usingExtension = false) => { +export const login = async ({privkey, pubkey}: {privkey?: string, pubkey?: string}) => { if (privkey) { keys.setPrivateKey(privkey) } else { diff --git a/src/partials/RelayCard.svelte b/src/partials/RelayCard.svelte new file mode 100644 index 00000000..30cc58ed --- /dev/null +++ b/src/partials/RelayCard.svelte @@ -0,0 +1,87 @@ + + +
+
+
+ + {last(relay.url.split('://'))} + {#if joined} + {showStatus = false}} + on:mouseover={() => {showStatus = true}} + class="w-2 h-2 rounded-full bg-medium cursor-pointer" + class:bg-danger={status === 'error'} + class:bg-warning={['pending', 'slow'].includes(status)} + class:bg-success={status === 'ready'}> + +

+ {switcher(status, { + error: 'Not connected', + pending: 'Trying to connect', + slow: 'Slow connection', + ready: 'Connected', + default: 'Waiting to reconnect', + })} +

+ {/if} +
+ {#if joined} + + {:else} + + {/if} +
+ {#if relay.description} +

{relay.description}

+ {/if} + {#if joined && showControls} +
+
+ Publish to this relay? + setRelayWriteCondition(relay.url, relay.write === "!" ? "" : "!")} /> +
+ {/if} +
diff --git a/src/routes/Login.svelte b/src/routes/Login.svelte index 58a2648a..2ecb6f7a 100644 --- a/src/routes/Login.svelte +++ b/src/routes/Login.svelte @@ -11,7 +11,7 @@ const {nostr} = window as any if (nostr) { - await login({pubkey: await nostr.getPublicKey()}, true) + await login({pubkey: await nostr.getPublicKey()}) } else { modal.set({type: 'login/privkey'}) } diff --git a/src/routes/RelayList.svelte b/src/routes/RelayList.svelte index 8029c6df..0417a0b6 100644 --- a/src/routes/RelayList.svelte +++ b/src/routes/RelayList.svelte @@ -1,17 +1,17 @@ @@ -18,20 +15,10 @@ {#if (person.relays || []).length === 0}
No relays found
{:else} - {#each person.relays as {url, write}, i (url)} -
-
- - - {last(url.split('://'))} - - {#if find(whereEq({url}), $user.relays)} - removeRelay({url})}>Leave - {:else} - addRelay({url})}>Join - {/if} -
-
+ {#each person.relays as relay, i (relay.url)} + {#if relay.write !== '!'} + + {/if} {/each} {/if}