mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-18 19:23:40 +00:00
Prompt user to select a relay on login
This commit is contained in:
parent
d4aaf98985
commit
9dc5c01241
@ -13,7 +13,10 @@
|
||||
- [x] Make chat header overlap main header to save space
|
||||
- [x] Strip formatting when pasting into Compose
|
||||
- [x] Upgraded nostr-tools to 1.4.1
|
||||
)
|
||||
- [x] Improve anonymous and new user experience by prompting for relays and follows
|
||||
- [x] Fixed kind0 merging to avoid dropping properties coracle doesn't support
|
||||
- [x] Implement NIP-65 properly
|
||||
|
||||
## 0.2.11
|
||||
|
||||
- [x] Converted threshold to percentage
|
||||
|
@ -1,9 +1,7 @@
|
||||
# Current
|
||||
|
||||
- [ ] Fix profile merging, put kind0 on its own property so we're not messing other people's profile data up.
|
||||
- [ ] Fix anon/new user experience
|
||||
- [ ] When logging in rather than generating a new keypair, ask for a relay to bootstrap from
|
||||
- [ ] Preload/wait for our big list of relays so we can offer suggestions. Search in the background and let them know if we found their profile.
|
||||
- [ ] Clicking stuff that would publish kicks you to the login page, we should open a modal instead.
|
||||
- [ ] Test publishing events with zero relays
|
||||
- [ ] Try lumping tables into a single key each to reduce load/save contention and time
|
||||
|
@ -18,7 +18,7 @@
|
||||
import keys from 'src/agent/keys'
|
||||
import network from 'src/agent/network'
|
||||
import pool from 'src/agent/pool'
|
||||
import {getUserRelays} from 'src/agent/relays'
|
||||
import {getUserRelays, initializeRelayList} from 'src/agent/relays'
|
||||
import sync from 'src/agent/sync'
|
||||
import user from 'src/agent/user'
|
||||
import {loadAppData} from "src/app"
|
||||
@ -41,6 +41,7 @@
|
||||
import PersonShare from "src/views/PersonShare.svelte"
|
||||
import PrivKeyLogin from "src/views/PrivKeyLogin.svelte"
|
||||
import PubKeyLogin from "src/views/PubKeyLogin.svelte"
|
||||
import ConnectUser from "src/views/ConnectUser.svelte"
|
||||
import SignUp from "src/views/SignUp.svelte"
|
||||
import AddRelay from "src/routes/AddRelay.svelte"
|
||||
import Alerts from "src/routes/Alerts.svelte"
|
||||
@ -110,6 +111,8 @@
|
||||
})
|
||||
|
||||
database.onReady(() => {
|
||||
initializeRelayList()
|
||||
|
||||
if (user.getProfile()) {
|
||||
loadAppData(user.getPubkey())
|
||||
}
|
||||
@ -126,7 +129,7 @@
|
||||
// few so we're not sending too many concurrent http requests
|
||||
const staleRelays = shuffle(
|
||||
await database.relays.all({
|
||||
'refreshed_at:lt': now() - timedelta(7, 'days'),
|
||||
'refreshed_at:lt': now() - timedelta(7, 'days'),
|
||||
})
|
||||
).slice(0, 10)
|
||||
|
||||
@ -237,6 +240,8 @@
|
||||
<PrivKeyLogin />
|
||||
{:else if $modal.type === 'login/pubkey'}
|
||||
<PubKeyLogin />
|
||||
{:else if $modal.type === 'login/connect'}
|
||||
<ConnectUser />
|
||||
{:else if $modal.type === 'person/settings'}
|
||||
<PersonSettings />
|
||||
{:else if $modal.type === 'person/share'}
|
||||
|
@ -233,23 +233,7 @@ const people = new Table('people', 'pubkey')
|
||||
const rooms = new Table('rooms', 'id')
|
||||
const messages = new Table('messages', 'id')
|
||||
const alerts = new Table('alerts', 'id')
|
||||
|
||||
const relays = new Table('relays', 'url', {
|
||||
initialize: async table => {
|
||||
const data = await table.dump()
|
||||
const defaults = createMap('url', [
|
||||
{url: 'wss://brb.io'},
|
||||
{url: 'wss://nostr.zebedee.cloud'},
|
||||
{url: 'wss://nostr-pub.wellorder.net'},
|
||||
{url: 'wss://relay.nostr.band'},
|
||||
{url: 'wss://nostr.pleb.network'},
|
||||
{url: 'wss://relay.nostrich.de'},
|
||||
{url: 'wss://relay.damus.io'},
|
||||
])
|
||||
|
||||
return Object.assign(data, defaults)
|
||||
},
|
||||
})
|
||||
const relays = new Table('relays', 'url')
|
||||
|
||||
const routes = new Table('routes', 'id', {
|
||||
initialize: async table => {
|
||||
|
@ -1,7 +1,8 @@
|
||||
import type {Relay} from 'src/util/types'
|
||||
import {pick, map, assoc, sortBy, uniqBy, prop} from 'ramda'
|
||||
import {first} from 'hurdak/lib/hurdak'
|
||||
import {Tags, findReplyId} from 'src/util/nostr'
|
||||
import {warn} from 'src/util/logger'
|
||||
import {pick, objOf, map, assoc, sortBy, uniqBy, prop} from 'ramda'
|
||||
import {first, createMap} from 'hurdak/lib/hurdak'
|
||||
import {Tags, isRelay, findReplyId} from 'src/util/nostr'
|
||||
import database from 'src/agent/database'
|
||||
import user from 'src/agent/user'
|
||||
|
||||
@ -17,6 +18,33 @@ import user from 'src/agent/user'
|
||||
// doesn't need to see.
|
||||
// 5) Advertise relays — write and read back your own relay list
|
||||
|
||||
// Initialize our database
|
||||
|
||||
export const initializeRelayList = async () => {
|
||||
// Throw some hardcoded defaults in there
|
||||
await database.relays.bulkPatch(
|
||||
createMap('url', [
|
||||
{url: 'wss://brb.io'},
|
||||
{url: 'wss://nostr.zebedee.cloud'},
|
||||
{url: 'wss://nostr-pub.wellorder.net'},
|
||||
{url: 'wss://relay.nostr.band'},
|
||||
{url: 'wss://nostr.pleb.network'},
|
||||
{url: 'wss://relay.nostrich.de'},
|
||||
{url: 'wss://relay.damus.io'},
|
||||
])
|
||||
)
|
||||
|
||||
// Load relays from nostr.watch via dufflepud
|
||||
try {
|
||||
const url = import.meta.env.VITE_DUFFLEPUD_URL + '/relay'
|
||||
const relays = prop('relays', await fetch(url).then(r => r.json())).filter(isRelay)
|
||||
|
||||
await database.relays.bulkPatch(createMap('url', map(objOf('url'), relays)))
|
||||
} catch (e) {
|
||||
warn("Failed to fetch relays list", e)
|
||||
}
|
||||
}
|
||||
|
||||
// Pubkey relays
|
||||
|
||||
export const getPubkeyRelays = (pubkey, mode = null) => {
|
||||
|
@ -1,19 +1,16 @@
|
||||
import type {DisplayEvent} from 'src/util/types'
|
||||
import {objOf, omit, sortBy, identity} from 'ramda'
|
||||
import {get} from 'svelte/store'
|
||||
import {navigate} from 'svelte-routing'
|
||||
import {omit, sortBy, identity} from 'ramda'
|
||||
import {createMap, ellipsize} from 'hurdak/lib/hurdak'
|
||||
import {renderContent} from 'src/util/html'
|
||||
import {shuffle} from 'src/util/misc'
|
||||
import {Tags, displayPerson, findReplyId} from 'src/util/nostr'
|
||||
import {getNetwork} from 'src/agent/social'
|
||||
import {getUserFollows} from 'src/agent/social'
|
||||
import {getUserReadRelays} from 'src/agent/relays'
|
||||
import database from 'src/agent/database'
|
||||
import network from 'src/agent/network'
|
||||
import keys from 'src/agent/keys'
|
||||
import alerts from 'src/app/alerts'
|
||||
import messages from 'src/app/messages'
|
||||
import {routes, settings, modal} from 'src/app/ui'
|
||||
import {routes, modal} from 'src/app/ui'
|
||||
|
||||
export const loadAppData = async pubkey => {
|
||||
if (getUserReadRelays().length > 0) {
|
||||
@ -21,7 +18,7 @@ export const loadAppData = async pubkey => {
|
||||
alerts.load(pubkey),
|
||||
alerts.listen(pubkey),
|
||||
messages.listen(pubkey),
|
||||
network.loadPeople(getNetwork(pubkey)),
|
||||
network.loadPeople(getUserFollows()),
|
||||
])
|
||||
}
|
||||
}
|
||||
@ -33,40 +30,7 @@ export const login = async ({privkey, pubkey}: {privkey?: string, pubkey?: strin
|
||||
keys.setPublicKey(pubkey)
|
||||
}
|
||||
|
||||
modal.set({
|
||||
type: 'message',
|
||||
message: "Loading your profile data...",
|
||||
spinner: true,
|
||||
noEscape: true,
|
||||
})
|
||||
|
||||
// Get a reasonably sized sample of relays and ask them all for relay information
|
||||
// for our user so we can bootstrap. This could be improved.
|
||||
let relays = []
|
||||
try {
|
||||
relays = (
|
||||
await fetch(get(settings).dufflepudUrl + '/relay').then(r => r.json())
|
||||
).relays.map(objOf('url'))
|
||||
} catch (e) {
|
||||
relays = database.relays.all()
|
||||
}
|
||||
|
||||
// Load our user so we can populate network and show profile info
|
||||
await network.loadPeople([pubkey], {
|
||||
relays: shuffle(relays).slice(0, 50),
|
||||
})
|
||||
|
||||
if (getUserReadRelays().length === 0) {
|
||||
navigate('/relays')
|
||||
} else {
|
||||
// Load network and start listening, but don't wait for it
|
||||
loadAppData(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/network')
|
||||
}
|
||||
modal.set({type: 'login/connect', noEscape: true})
|
||||
}
|
||||
|
||||
export const renderNote = (note, {showEntire = false}) => {
|
||||
|
89
src/views/ConnectUser.svelte
Normal file
89
src/views/ConnectUser.svelte
Normal file
@ -0,0 +1,89 @@
|
||||
<script lang="ts">
|
||||
import {pluck, reject, last} from 'ramda'
|
||||
import {navigate} from 'svelte-routing'
|
||||
import {displayList} from 'hurdak/lib/hurdak'
|
||||
import {sleep} from 'src/util/misc'
|
||||
import Content from 'src/partials/Content.svelte'
|
||||
import Spinner from 'src/partials/Spinner.svelte'
|
||||
import Heading from 'src/partials/Heading.svelte'
|
||||
import Anchor from 'src/partials/Anchor.svelte'
|
||||
import Input from 'src/partials/Input.svelte'
|
||||
import Modal from 'src/partials/Modal.svelte'
|
||||
import {getUserReadRelays} from 'src/agent/relays'
|
||||
import database from 'src/agent/database'
|
||||
import network from 'src/agent/network'
|
||||
import user from 'src/agent/user'
|
||||
import {loadAppData} from 'src/app'
|
||||
|
||||
let url = ''
|
||||
let message = null
|
||||
let currentRelays = []
|
||||
let attemptedRelays = new Set()
|
||||
let knownRelays = database.watch('relays', table => table.all())
|
||||
|
||||
const searchSample = async () => {
|
||||
currentRelays = reject(r => attemptedRelays.has(r.url), $knownRelays).slice(0, 10)
|
||||
currentRelays.forEach(({url}) => attemptedRelays.add(url))
|
||||
|
||||
if (currentRelays.length === 0) {
|
||||
message = `
|
||||
We weren't able to find your profile data, you'll need to select your
|
||||
relays manually to continue.`
|
||||
|
||||
await sleep(3000)
|
||||
|
||||
navigate('/relays')
|
||||
} else {
|
||||
await network.loadPeople([user.getPubkey()], {relays: currentRelays})
|
||||
|
||||
console.log(user.getProfile(), getUserReadRelays())
|
||||
if (getUserReadRelays().length > 0) {
|
||||
message = `Success! Just a moment while we get things set up.`
|
||||
|
||||
await Promise.all([
|
||||
loadAppData(user.getPubkey()),
|
||||
sleep(3000),
|
||||
])
|
||||
|
||||
navigate('/notes/network')
|
||||
} else {
|
||||
await sleep(1000)
|
||||
|
||||
searchSample()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const skip = () => {
|
||||
navigate('/notes/network')
|
||||
}
|
||||
|
||||
searchSample()
|
||||
</script>
|
||||
|
||||
<Content size="lg" class="text-center">
|
||||
<Heading>Connect to Nostr</Heading>
|
||||
<p class="text-left">
|
||||
We're searching for your profile on the network. If you'd like to select your
|
||||
relays manually instead, click <Anchor on:click={skip}>here</Anchor>.
|
||||
</p>
|
||||
{#if currentRelays.length > 0}
|
||||
<p class="text-left">
|
||||
Currently searching:
|
||||
</p>
|
||||
<ul class="text-left list-disc ml-6">
|
||||
{#each currentRelays as relay}
|
||||
<li>{last(relay.url.split('://'))}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
</Content>
|
||||
|
||||
{#if message}
|
||||
<Modal nested>
|
||||
<Content size="lg" class="text-center">
|
||||
{message}
|
||||
<Spinner delay={0} />
|
||||
</Content>
|
||||
</Modal>
|
||||
{/if}
|
@ -24,6 +24,7 @@
|
||||
})
|
||||
|
||||
// Prime our database, in case we don't have any people stored yet
|
||||
console.log(getUserReadRelays())
|
||||
network.listenUntilEose(getUserReadRelays(), {kinds: personKinds, limit: 300})
|
||||
</script>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user