mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-30 00:41:12 +00:00
Support nevent path
This commit is contained in:
parent
e0bb3ca32c
commit
2f818a561e
@ -74,6 +74,7 @@ If you like Coracle and want to support its development, you can donate sats via
|
||||
- [ ] Load feeds from network rather than user relays? This could make global feed more useful: global for _my_ relays
|
||||
- [ ] Release to android with https://svelte-native.technology/docs
|
||||
- [ ] Compress is taking too long and messing up the ui, maybe use dexie for people?
|
||||
- [ ] Move people to nprofile via bech32 entity (or redirect from there)
|
||||
|
||||
## 0.2.6
|
||||
|
||||
|
@ -15,7 +15,8 @@
|
||||
import {modal, toast, settings, alerts} from "src/app"
|
||||
import {routes} from "src/app/ui"
|
||||
import Anchor from 'src/partials/Anchor.svelte'
|
||||
import NoteDetail from "src/views/NoteDetail.svelte"
|
||||
import Modal from 'src/partials/Modal.svelte'
|
||||
import NoteDetailModal from "src/views/NoteDetail.svelte"
|
||||
import PersonSettings from "src/views/PersonSettings.svelte"
|
||||
import NotFound from "src/routes/NotFound.svelte"
|
||||
import Search from "src/routes/Search.svelte"
|
||||
@ -30,6 +31,7 @@
|
||||
import AddRelay from "src/routes/AddRelay.svelte"
|
||||
import Person from "src/routes/Person.svelte"
|
||||
import NoteCreate from "src/routes/NoteCreate.svelte"
|
||||
import Bech32Entity from "src/routes/Bech32Entity.svelte"
|
||||
|
||||
export let url = ""
|
||||
|
||||
@ -39,6 +41,11 @@
|
||||
const searchIsOpen = writable(false)
|
||||
const toggleSearch = () => searchIsOpen.update(x => !x)
|
||||
|
||||
const closeModal = () => {
|
||||
modal.set(null)
|
||||
menuIsOpen.set(false)
|
||||
}
|
||||
|
||||
let menuIcon
|
||||
let scrollY
|
||||
let suspendedSubs = []
|
||||
@ -78,14 +85,6 @@
|
||||
})
|
||||
</script>
|
||||
|
||||
<svelte:body
|
||||
on:keydown={e => {
|
||||
if (e.key === 'Escape') {
|
||||
modal.set(null)
|
||||
menuIsOpen.set(false)
|
||||
}
|
||||
}} />
|
||||
|
||||
<Router {url}>
|
||||
<div use:links class="h-full">
|
||||
<div class="pt-16 text-white h-full">
|
||||
@ -104,6 +103,11 @@
|
||||
<Route path="/settings" component={Settings} />
|
||||
<Route path="/login" component={Login} />
|
||||
<Route path="/logout" component={Logout} />
|
||||
<Route path="/:entity" let:params>
|
||||
{#key params.entity}
|
||||
<Bech32Entity {...params} />
|
||||
{/key}
|
||||
</Route>
|
||||
<Route path="*" component={NotFound} />
|
||||
</div>
|
||||
|
||||
@ -197,25 +201,17 @@
|
||||
{/if}
|
||||
|
||||
{#if $modal}
|
||||
<div class="fixed inset-0 z-10">
|
||||
<div
|
||||
class="absolute inset-0 opacity-75 bg-black cursor-pointer"
|
||||
transition:fade
|
||||
on:click={e => modal.set(null)} />
|
||||
<div class="absolute inset-0 mt-20 sm:mt-32 modal-content" transition:fly={{y: 1000, opacity: 1}}>
|
||||
<dialog open class="bg-dark border-t border-solid border-medium h-full w-full overflow-auto">
|
||||
{#if $modal.note}
|
||||
{#key $modal.note.id}
|
||||
<NoteDetail {...$modal} />
|
||||
{/key}
|
||||
{:else if $modal.form === 'relay'}
|
||||
<AddRelay />
|
||||
{:else if $modal.form === 'person/settings'}
|
||||
<PersonSettings />
|
||||
{/if}
|
||||
</dialog>
|
||||
</div>
|
||||
</div>
|
||||
<Modal onEscape={closeModal}>
|
||||
{#if $modal.note}
|
||||
{#key $modal.note.id}
|
||||
<NoteDetailModal {...$modal} />
|
||||
{/key}
|
||||
{:else if $modal.form === 'relay'}
|
||||
<AddRelay />
|
||||
{:else if $modal.form === 'person/settings'}
|
||||
<PersonSettings />
|
||||
{/if}
|
||||
</Modal>
|
||||
{/if}
|
||||
|
||||
{#if $toast}
|
||||
|
@ -46,6 +46,10 @@ export const getRelays = pubkey => {
|
||||
}
|
||||
|
||||
export const getEventRelays = event => {
|
||||
if (event.seen_on) {
|
||||
return [event.seen_on]
|
||||
}
|
||||
|
||||
return uniq(getRelays(event.pubkey).concat(Tags.from(event).relays()))
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
import {without} from 'ramda'
|
||||
import {updateIn, mergeRight} from 'hurdak/lib/hurdak'
|
||||
import {get} from 'svelte/store'
|
||||
import {getPerson, getRelays, people, keys, db} from 'src/agent'
|
||||
import {getPerson, getRelays, people, load, keys, db} from 'src/agent'
|
||||
import {toast, modal, settings} from 'src/app/ui'
|
||||
import cmd from 'src/app/cmd'
|
||||
import alerts from 'src/app/alerts'
|
||||
import loaders from 'src/app/loaders'
|
||||
import query from 'src/app/query'
|
||||
|
||||
export {toast, modal, settings, alerts}
|
||||
|
||||
@ -49,3 +50,19 @@ export const removeRelay = async url => {
|
||||
|
||||
await cmd.setRelays(without([url], relays))
|
||||
}
|
||||
|
||||
export const loadNote = async (relays, id) => {
|
||||
const [found] = await load(relays, {ids: [id]})
|
||||
|
||||
if (!found) {
|
||||
return null
|
||||
}
|
||||
|
||||
const context = await loaders.loadContext(relays, found)
|
||||
const note = query.annotate(found, context, {showEntire: true, depth: 3})
|
||||
|
||||
// Log this for debugging purposes
|
||||
console.log('loadNote', note)
|
||||
|
||||
return note
|
||||
}
|
||||
|
24
src/partials/Modal.svelte
Normal file
24
src/partials/Modal.svelte
Normal file
@ -0,0 +1,24 @@
|
||||
<script>
|
||||
import {fly, fade} from "svelte/transition"
|
||||
|
||||
export let onEscape
|
||||
</script>
|
||||
|
||||
<svelte:body
|
||||
on:keydown={e => {
|
||||
if (e.key === 'Escape') {
|
||||
onEscape()
|
||||
}
|
||||
}} />
|
||||
|
||||
<div class="fixed inset-0 z-10">
|
||||
<div
|
||||
class="absolute inset-0 opacity-75 bg-black cursor-pointer"
|
||||
transition:fade
|
||||
on:click={onEscape} />
|
||||
<div class="absolute inset-0 mt-20 sm:mt-32 modal-content" transition:fly={{y: 1000, opacity: 1}}>
|
||||
<dialog open class="bg-dark border-t border-solid border-medium h-full w-full overflow-auto">
|
||||
<slot />
|
||||
</dialog>
|
||||
</div>
|
||||
</div>
|
@ -1,6 +1,7 @@
|
||||
<script>
|
||||
import cx from 'classnames'
|
||||
import extractUrls from 'extract-urls'
|
||||
import {nip19} from 'nostr-tools'
|
||||
import {whereEq, reject, propEq, find} from 'ramda'
|
||||
import {slide} from 'svelte/transition'
|
||||
import {navigate} from 'svelte-routing'
|
||||
@ -27,6 +28,7 @@
|
||||
|
||||
const links = $settings.showLinkPreviews ? extractUrls(note.content) || [] : null
|
||||
const interactive = !anchorId || anchorId !== note.id
|
||||
const relays = getEventRelays(note)
|
||||
|
||||
let likes, flags, like, flag
|
||||
|
||||
@ -40,15 +42,14 @@
|
||||
|
||||
const onClick = e => {
|
||||
if (!['I'].includes(e.target.tagName) && !hasParent('a', e.target)) {
|
||||
modal.set({note, relays: getEventRelays(note)})
|
||||
modal.set({note, relays})
|
||||
}
|
||||
}
|
||||
|
||||
const goToParent = async () => {
|
||||
modal.set({
|
||||
note: {id: findReply(note)[1]},
|
||||
relays: getEventRelays(note),
|
||||
})
|
||||
const parent = {id: findReply(note)[1]}
|
||||
|
||||
modal.set({note: parent, relays})
|
||||
}
|
||||
|
||||
const react = async content => {
|
||||
@ -114,7 +115,12 @@
|
||||
<Card on:click={onClick} {interactive} {invertColors}>
|
||||
<div class="flex gap-4 items-center justify-between">
|
||||
<Badge person={getPerson(note.pubkey, true)} />
|
||||
<p class="text-sm text-light">{formatTimestamp(note.created_at)}</p>
|
||||
<Anchor
|
||||
href={"/" + nip19.neventEncode({id: note.id, relays})}
|
||||
class="text-sm text-light"
|
||||
type="unstyled">
|
||||
{formatTimestamp(note.created_at)}
|
||||
</Anchor>
|
||||
</div>
|
||||
<div class="ml-6 flex flex-col gap-2">
|
||||
{#if findReply(note) && showParent}
|
||||
|
15
src/routes/Bech32Entity.svelte
Normal file
15
src/routes/Bech32Entity.svelte
Normal file
@ -0,0 +1,15 @@
|
||||
<script>
|
||||
import {nip19} from 'nostr-tools'
|
||||
import NoteDetail from 'src/routes/NoteDetail.svelte'
|
||||
|
||||
export let entity
|
||||
|
||||
const {type, data} = nip19.decode(entity)
|
||||
</script>
|
||||
|
||||
<div class="py-4 max-w-xl m-auto">
|
||||
{#if type === "nevent"}
|
||||
<NoteDetail {...data} />
|
||||
{/if}
|
||||
</div>
|
||||
|
29
src/routes/NoteDetail.svelte
Normal file
29
src/routes/NoteDetail.svelte
Normal file
@ -0,0 +1,29 @@
|
||||
<script>
|
||||
import {fly} from 'svelte/transition'
|
||||
import {loadNote} from 'src/app'
|
||||
import Note from 'src/partials/Note.svelte'
|
||||
import Spinner from 'src/partials/Spinner.svelte'
|
||||
|
||||
export let id
|
||||
export let relays
|
||||
|
||||
let note = {id}
|
||||
|
||||
console.log(id, relays)
|
||||
|
||||
loadNote(relays, id).then(found => {
|
||||
note = found
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if !note}
|
||||
<div class="p-4 text-center text-white" in:fly={{y: 20}}>
|
||||
Sorry, we weren't able to find this note.
|
||||
</div>
|
||||
{:else if note.pubkey}
|
||||
<div in:fly={{y: 20}}>
|
||||
<Note invertColors anchorId={note.id} note={note} depth={2} />
|
||||
</div>
|
||||
{:else}
|
||||
<Spinner />
|
||||
{/if}
|
@ -1,9 +1,6 @@
|
||||
<script>
|
||||
import {first} from 'hurdak/lib/hurdak'
|
||||
import {fly} from 'svelte/transition'
|
||||
import {load} from 'src/agent'
|
||||
import loaders from 'src/app/loaders'
|
||||
import query from 'src/app/query'
|
||||
import {loadNote} from 'src/app'
|
||||
import Note from 'src/partials/Note.svelte'
|
||||
import Spinner from 'src/partials/Spinner.svelte'
|
||||
|
||||
@ -11,18 +8,11 @@
|
||||
export let relays
|
||||
|
||||
if (!note.pubkey) {
|
||||
load(relays, {ids: [note.id]}).then(async events => {
|
||||
const found = first(events)
|
||||
|
||||
if (found) {
|
||||
const context = await loaders.loadContext(relays, found)
|
||||
|
||||
note = query.annotate(found, context, {showEntire: true, depth: 3})
|
||||
}
|
||||
|
||||
// Log this for debugging purposes
|
||||
console.log('NoteDetail', note)
|
||||
loadNote(relays, note.id).then(found => {
|
||||
note = found
|
||||
})
|
||||
} else {
|
||||
console.log('NoteDetail', note)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user