mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-29 00:10:52 +00:00
Add support for custom relay urls
This commit is contained in:
parent
7612db163e
commit
766a1055de
@ -1,12 +1,12 @@
|
|||||||
Bugs
|
Bugs
|
||||||
|
|
||||||
- [ ] Remove dexie, or use it instead of localstorage for cached data
|
|
||||||
- [ ] Memoize room list, currently every time the user switches chat rooms it pulls the full list
|
- [ ] Memoize room list, currently every time the user switches chat rooms it pulls the full list
|
||||||
- [ ] Fix toast, it gets in the way. Make it smaller and dismissable.
|
- [ ] Fix toast, it gets in the way. Make it smaller and dismissable.
|
||||||
|
|
||||||
Features
|
Features
|
||||||
|
|
||||||
- [ ] Threads/social
|
- [x] Chat
|
||||||
|
- [x] Threads/social
|
||||||
- [ ] Followers
|
- [ ] Followers
|
||||||
- [ ] Server discovery
|
- [ ] Server discovery
|
||||||
- [ ] Favorite chat rooms
|
- [ ] Favorite chat rooms
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
import Profile from "src/routes/Profile.svelte"
|
import Profile from "src/routes/Profile.svelte"
|
||||||
import Keys from "src/routes/Keys.svelte"
|
import Keys from "src/routes/Keys.svelte"
|
||||||
import RelayList from "src/routes/RelayList.svelte"
|
import RelayList from "src/routes/RelayList.svelte"
|
||||||
|
import AddRelay from "src/routes/AddRelay.svelte"
|
||||||
import UserDetail from "src/routes/UserDetail.svelte"
|
import UserDetail from "src/routes/UserDetail.svelte"
|
||||||
import NoteCreate from "src/routes/NoteCreate.svelte"
|
import NoteCreate from "src/routes/NoteCreate.svelte"
|
||||||
import Chat from "src/routes/Chat.svelte"
|
import Chat from "src/routes/Chat.svelte"
|
||||||
@ -143,6 +144,8 @@
|
|||||||
{#key $modal.note.id}
|
{#key $modal.note.id}
|
||||||
<NoteDetail note={$modal.note} />
|
<NoteDetail note={$modal.note} />
|
||||||
{/key}
|
{/key}
|
||||||
|
{:else if $modal.form === 'relay'}
|
||||||
|
<AddRelay />
|
||||||
{/if}
|
{/if}
|
||||||
</dialog>
|
</dialog>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
import {onMount} from 'svelte'
|
import {onMount} from 'svelte'
|
||||||
import {find, propEq} from 'ramda'
|
import {find, propEq} from 'ramda'
|
||||||
import {findNotes} from "src/state/app"
|
import {findNotes} from "src/state/app"
|
||||||
import {channels} from "src/state/nostr"
|
|
||||||
import {user} from "src/state/user"
|
import {user} from "src/state/user"
|
||||||
import Note from 'src/partials/Note.svelte'
|
import Note from 'src/partials/Note.svelte'
|
||||||
|
|
||||||
|
41
src/routes/AddRelay.svelte
Normal file
41
src/routes/AddRelay.svelte
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<script>
|
||||||
|
import {fly} from 'svelte/transition'
|
||||||
|
import {registerRelay} from 'src/state/nostr'
|
||||||
|
import toast from 'src/state/toast'
|
||||||
|
import {modal} from 'src/state/app'
|
||||||
|
import Input from 'src/partials/Input.svelte'
|
||||||
|
import Button from 'src/partials/Button.svelte'
|
||||||
|
|
||||||
|
let url = ''
|
||||||
|
|
||||||
|
const submit = e => {
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
if (!url.match(/^wss?:\/\/[\w.:-]+$/)) {
|
||||||
|
return toast.show("error", 'That isn\'t a valid websocket url - relay urls should start with "wss://"')
|
||||||
|
}
|
||||||
|
|
||||||
|
registerRelay(url)
|
||||||
|
modal.set(null)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form on:submit={submit} class="flex justify-center py-8 px-4 text-white" in:fly={{y: 20}}>
|
||||||
|
<div class="flex flex-col gap-4 max-w-2xl flex-grow">
|
||||||
|
<div class="flex justify-center items-center flex-col mb-4">
|
||||||
|
<h1 class="staatliches text-6xl">Add a relay</h1>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-8 w-full">
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<strong>Relay URL</strong>
|
||||||
|
<Input bind:value={url}>
|
||||||
|
<i slot="before" class="fa-solid fa-link" />
|
||||||
|
</Input>
|
||||||
|
<p class="text-sm text-light">
|
||||||
|
The url where the relay is hosted.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<Button type="submit" class="text-center">Done</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
@ -1,5 +1,14 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import {onMount} from "svelte"
|
||||||
|
import {navigate} from "svelte-routing"
|
||||||
import RoomList from "src/partials/chat/RoomList.svelte"
|
import RoomList from "src/partials/chat/RoomList.svelte"
|
||||||
|
import {user} from "src/state/user"
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (!$user) {
|
||||||
|
return navigate('/login')
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex gap-4 h-full">
|
<div class="flex gap-4 h-full">
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
<script>
|
<script>
|
||||||
import {onMount} from 'svelte'
|
import {onMount} from 'svelte'
|
||||||
import {navigate} from "svelte-routing"
|
import {navigate} from "svelte-routing"
|
||||||
import {timedelta, now} from 'src/util/misc'
|
|
||||||
import Anchor from "src/partials/Anchor.svelte"
|
import Anchor from "src/partials/Anchor.svelte"
|
||||||
import Note from "src/partials/Note.svelte"
|
import Note from "src/partials/Note.svelte"
|
||||||
import {channels, relays} from "src/state/nostr"
|
import {relays} from "src/state/nostr"
|
||||||
import {findNotesAndWatchModal, modal} from "src/state/app"
|
import {findNotesAndWatchModal} from "src/state/app"
|
||||||
|
|
||||||
let notes
|
let notes
|
||||||
|
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
<script>
|
<script>
|
||||||
import {liveQuery} from "dexie"
|
|
||||||
import {fly} from 'svelte/transition'
|
import {fly} from 'svelte/transition'
|
||||||
import {fuzzy} from "src/util/misc"
|
import {fuzzy} from "src/util/misc"
|
||||||
import Input from "src/partials/Input.svelte"
|
import Input from "src/partials/Input.svelte"
|
||||||
import Anchor from "src/partials/Anchor.svelte"
|
import Anchor from "src/partials/Anchor.svelte"
|
||||||
import {db} from "src/state/db"
|
|
||||||
import {dispatch} from "src/state/dispatch"
|
import {dispatch} from "src/state/dispatch"
|
||||||
import {relays} from "src/state/nostr"
|
import {modal} from "src/state/app"
|
||||||
|
import {relays, knownRelays} from "src/state/nostr"
|
||||||
|
|
||||||
let q = ""
|
let q = ""
|
||||||
let search
|
let search
|
||||||
|
|
||||||
const knownRelays = liveQuery(() => db.relays.toArray())
|
|
||||||
|
|
||||||
$: search = fuzzy($knownRelays || [], {keys: ["name", "description", "url"]})
|
$: search = fuzzy($knownRelays || [], {keys: ["name", "description", "url"]})
|
||||||
|
|
||||||
const toggle = (url, value) => {
|
const toggle = (url, value) => {
|
||||||
@ -36,7 +33,7 @@
|
|||||||
<Anchor type="button" href="/notes">Done</Anchor>
|
<Anchor type="button" href="/notes">Done</Anchor>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-6 overflow-auto flex-grow -mx-6 px-6">
|
<div class="flex flex-col gap-6 overflow-auto flex-grow -mx-6 px-6">
|
||||||
{#each search(q) as relay}
|
{#each search(q).slice(0, 10) as relay}
|
||||||
<div class="flex gap-2 justify-between">
|
<div class="flex gap-2 justify-between">
|
||||||
<div>
|
<div>
|
||||||
<strong>{relay.name || relay.url}</strong>
|
<strong>{relay.name || relay.url}</strong>
|
||||||
@ -49,6 +46,11 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
<a
|
||||||
|
class="underline cursor-pointer"
|
||||||
|
on:click={() => modal.set({form: 'relay'})}>
|
||||||
|
<i class="fa-solid fa-plus" /> Add Relay
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,11 +2,9 @@
|
|||||||
import {onMount} from 'svelte'
|
import {onMount} from 'svelte'
|
||||||
import {reverse} from 'ramda'
|
import {reverse} from 'ramda'
|
||||||
import {fly} from 'svelte/transition'
|
import {fly} from 'svelte/transition'
|
||||||
import {now, timedelta} from 'src/util/misc'
|
|
||||||
import Note from "src/partials/Note.svelte"
|
import Note from "src/partials/Note.svelte"
|
||||||
import {channels} from 'src/state/nostr'
|
|
||||||
import {user as currentUser} from 'src/state/user'
|
import {user as currentUser} from 'src/state/user'
|
||||||
import {accounts, findNotesAndWatchModal, modal} from "src/state/app"
|
import {accounts, findNotesAndWatchModal} from "src/state/app"
|
||||||
|
|
||||||
export let pubkey
|
export let pubkey
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import {prop, uniq, sortBy, uniqBy, find, last, groupBy} from 'ramda'
|
|||||||
import {debounce} from 'throttle-debounce'
|
import {debounce} from 'throttle-debounce'
|
||||||
import {writable, derived, get} from 'svelte/store'
|
import {writable, derived, get} from 'svelte/store'
|
||||||
import {navigate} from "svelte-routing"
|
import {navigate} from "svelte-routing"
|
||||||
import {switcherFn, noop, ensurePlural} from 'hurdak/lib/hurdak'
|
import {switcherFn, ensurePlural} from 'hurdak/lib/hurdak'
|
||||||
import {getLocalJson, setLocalJson, now, timedelta} from "src/util/misc"
|
import {getLocalJson, setLocalJson, now, timedelta} from "src/util/misc"
|
||||||
import {user} from 'src/state/user'
|
import {user} from 'src/state/user'
|
||||||
import {channels, relays} from 'src/state/nostr'
|
import {channels, relays} from 'src/state/nostr'
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
import {Dexie} from "dexie"
|
|
||||||
|
|
||||||
export const db = new Dexie("coracle/db", {})
|
|
||||||
|
|
||||||
db.version(2).stores({
|
|
||||||
relays: "url",
|
|
||||||
events: "id, pubkey",
|
|
||||||
})
|
|
||||||
|
|
||||||
db
|
|
||||||
.open()
|
|
||||||
.then(async db => {
|
|
||||||
console.log("Database ready")
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.error(err)
|
|
||||||
})
|
|
||||||
|
|
||||||
export const registerRelay = async url => {
|
|
||||||
let json
|
|
||||||
// try {
|
|
||||||
// const res = await fetch(url.replace(/^ws/, 'http'), {
|
|
||||||
// headers: {
|
|
||||||
// Accept: 'application/nostr_json',
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
|
|
||||||
// json = await res.json()
|
|
||||||
// } catch (e) {
|
|
||||||
// json = {}
|
|
||||||
// }
|
|
||||||
|
|
||||||
db.relays.put({...json, url})
|
|
||||||
}
|
|
||||||
|
|
||||||
registerRelay('wss://nostr-relay-dev.wlvs.space')
|
|
||||||
registerRelay('wss://nostr-pub.wellorder.net')
|
|
||||||
registerRelay('wss://nostr-relay.wlvs.space')
|
|
||||||
registerRelay('ws://localhost:7000')
|
|
@ -1,7 +1,7 @@
|
|||||||
import {writable} from 'svelte/store'
|
import {writable} from 'svelte/store'
|
||||||
import {debounce} from 'throttle-debounce'
|
import {debounce} from 'throttle-debounce'
|
||||||
import {relayPool, getPublicKey} from 'nostr-tools'
|
import {relayPool, getPublicKey} from 'nostr-tools'
|
||||||
import {last} from 'ramda'
|
import {last, uniqBy, prop} from 'ramda'
|
||||||
import {first} from 'hurdak/lib/hurdak'
|
import {first} from 'hurdak/lib/hurdak'
|
||||||
import {getLocalJson, setLocalJson} from "src/util/misc"
|
import {getLocalJson, setLocalJson} from "src/util/misc"
|
||||||
|
|
||||||
@ -91,6 +91,27 @@ nostr.event = (kind, content = '', tags = []) => {
|
|||||||
return {kind, content, tags, pubkey, created_at: createdAt}
|
return {kind, content, tags, pubkey, created_at: createdAt}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep track of known relays
|
||||||
|
|
||||||
|
export const knownRelays = writable(getLocalJson("coracle/knownRelays") || [])
|
||||||
|
|
||||||
|
export const registerRelay = async url => {
|
||||||
|
let json
|
||||||
|
try {
|
||||||
|
const res = await fetch(url.replace(/^ws/, 'http'), {
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/nostr_json',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
json = await res.json()
|
||||||
|
} catch (e) {
|
||||||
|
json = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
knownRelays.update($xs => uniqBy(prop('url'), $xs.concat({...json, url})))
|
||||||
|
}
|
||||||
|
|
||||||
// Create writable store for relays so we can observe changes in the app
|
// Create writable store for relays so we can observe changes in the app
|
||||||
|
|
||||||
export const relays = writable(getLocalJson("coracle/relays") || [])
|
export const relays = writable(getLocalJson("coracle/relays") || [])
|
||||||
|
@ -72,7 +72,7 @@ export const escapeHtml = html => {
|
|||||||
export const toHtml = content => {
|
export const toHtml = content => {
|
||||||
return escapeHtml(content)
|
return escapeHtml(content)
|
||||||
.replace(/\n/g, '<br />')
|
.replace(/\n/g, '<br />')
|
||||||
.replace(/https?:\/\/([\w\.-]+)[^ ]*/g, (url, domain) => {
|
.replace(/https?:\/\/([\w.-]+)[^ ]*/g, (url, domain) => {
|
||||||
return `<a href="${url}" target="_blank noopener" class="underline">${domain}</a>`
|
return `<a href="${url}" target="_blank noopener" class="underline">${domain}</a>`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user