Open a note in a modal instead of on a page of its own (#628)
This commit is contained in:
parent
cfc30803b4
commit
180ab5cb24
5 changed files with 56 additions and 47 deletions
|
|
@ -6,8 +6,8 @@
|
||||||
import Reply from "@assets/icons/reply-2.svg?dataurl"
|
import Reply from "@assets/icons/reply-2.svg?dataurl"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
import Page from "@lib/components/Page.svelte"
|
import Modal from "@lib/components/Modal.svelte"
|
||||||
import PageContent from "@lib/components/PageContent.svelte"
|
import ModalBody from "@lib/components/ModalBody.svelte"
|
||||||
import Spinner from "@lib/components/Spinner.svelte"
|
import Spinner from "@lib/components/Spinner.svelte"
|
||||||
import CommentCompose from "@app/components/CommentCompose.svelte"
|
import CommentCompose from "@app/components/CommentCompose.svelte"
|
||||||
import CommentTree from "@app/components/CommentTree.svelte"
|
import CommentTree from "@app/components/CommentTree.svelte"
|
||||||
|
|
@ -38,38 +38,34 @@
|
||||||
onDestroy(context.cleanup)
|
onDestroy(context.cleanup)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Page>
|
<Modal label="Note">
|
||||||
<PageContent noPad class="flex flex-col">
|
<ModalBody>
|
||||||
{#if $event}
|
{#if $event}
|
||||||
{@const note = $event}
|
{@const note = $event}
|
||||||
{@const replyToNote = () => setReplyTo(note)}
|
{@const replyToNote = () => setReplyTo(note)}
|
||||||
<div class="border-b border-line bg-surface px-4 py-4">
|
<div class="border-line flex flex-col gap-4 border-b pb-4">
|
||||||
<div class="mx-auto w-full max-w-[68ch]">
|
<NoteItem event={note} {context} card={false} showEntire>
|
||||||
<NoteItem event={note} {context} card={false} showEntire>
|
{#if replyTo?.id !== note.id}
|
||||||
{#if replyTo?.id !== note.id}
|
<Button class="button button-neutral button-xs" onclick={replyToNote}>
|
||||||
<Button class="button button-neutral button-xs" onclick={replyToNote}>
|
<Icon icon={Reply} size={4} />
|
||||||
<Icon icon={Reply} size={4} />
|
Reply
|
||||||
Reply
|
</Button>
|
||||||
</Button>
|
{/if}
|
||||||
{/if}
|
</NoteItem>
|
||||||
</NoteItem>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="mx-auto w-full max-w-[68ch] px-4 pt-4">
|
|
||||||
{#if replyTo?.id === note.id}
|
{#if replyTo?.id === note.id}
|
||||||
<div class="pb-4">
|
<CommentCompose
|
||||||
<CommentCompose
|
event={note}
|
||||||
event={note}
|
noun="Reply"
|
||||||
noun="Reply"
|
onCancel={clearReplyTo}
|
||||||
onCancel={clearReplyTo}
|
onSubmit={clearReplyTo} />
|
||||||
onSubmit={clearReplyTo} />
|
|
||||||
</div>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col">
|
||||||
{#each $replies as node (node.comment.id)}
|
{#each $replies as node (node.comment.id)}
|
||||||
<CommentTree {node} root={note} {replyTo} {setReplyTo} {context} />
|
<CommentTree {node} root={note} {replyTo} {setReplyTo} {context} />
|
||||||
{/each}
|
{/each}
|
||||||
{#if $replies.length === 0 && replyTo?.id !== note.id}
|
{#if $replies.length === 0}
|
||||||
<p class="py-6 text-sm opacity-75">No replies yet.</p>
|
<p class="py-2 text-sm opacity-75">No replies yet.</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
|
|
@ -81,5 +77,5 @@
|
||||||
{/await}
|
{/await}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</PageContent>
|
</ModalBody>
|
||||||
</Page>
|
</Modal>
|
||||||
|
|
@ -25,7 +25,9 @@ import {entityLink, PLATFORM_URL, PLATFORM_RELAYS} from "@app/env"
|
||||||
import {decodeRelay, encodeRelay} from "@app/relays"
|
import {decodeRelay, encodeRelay} from "@app/relays"
|
||||||
import {DM_KINDS} from "@app/content"
|
import {DM_KINDS} from "@app/content"
|
||||||
import {navigate, pushModal} from "@app/modal"
|
import {navigate, pushModal} from "@app/modal"
|
||||||
|
import type {NotePointer} from "@app/social"
|
||||||
import ChatEnable from "@app/components/ChatEnable.svelte"
|
import ChatEnable from "@app/components/ChatEnable.svelte"
|
||||||
|
import NoteDetail from "@app/components/NoteDetail.svelte"
|
||||||
|
|
||||||
// State
|
// State
|
||||||
|
|
||||||
|
|
@ -267,8 +269,23 @@ export const scrollToEvent = (id: string) => {
|
||||||
return element instanceof HTMLElement
|
return element instanceof HTMLElement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A note opens over whatever is on screen rather than on a page of its own.
|
||||||
|
export const pushNote = (pointer: NotePointer) => pushModal(NoteDetail, {pointer}, {size: "large"})
|
||||||
|
|
||||||
|
// A url resolving to a note has nothing on screen to open it over, so the app goes behind it.
|
||||||
|
export const goToNote = (pointer: NotePointer) => {
|
||||||
|
pushNote(pointer)
|
||||||
|
|
||||||
|
return goToHome()
|
||||||
|
}
|
||||||
|
|
||||||
export const goToEvent = (event: TrustedEvent, options: Record<string, any> = {}) => {
|
export const goToEvent = (event: TrustedEvent, options: Record<string, any> = {}) => {
|
||||||
const urls = Array.from(app.get().tracker.getRelays(event.id))
|
const urls = Array.from(app.get().tracker.getRelays(event.id))
|
||||||
|
|
||||||
|
if (event.kind === NOTE) {
|
||||||
|
return pushNote({id: event.id, pubkey: event.pubkey, relays: urls})
|
||||||
|
}
|
||||||
|
|
||||||
const path = makeEventPath(event, urls)
|
const path = makeEventPath(event, urls)
|
||||||
|
|
||||||
if (path.includes("://")) {
|
if (path.includes("://")) {
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,13 @@
|
||||||
import {onMount} from "svelte"
|
import {onMount} from "svelte"
|
||||||
import * as nip19 from "nostr-tools/nip19"
|
import * as nip19 from "nostr-tools/nip19"
|
||||||
import type {TrustedEvent} from "@welshman/util"
|
import type {TrustedEvent} from "@welshman/util"
|
||||||
import {Address, getIdFilters} from "@welshman/util"
|
import {Address, NOTE, getIdFilters} from "@welshman/util"
|
||||||
import {LOCAL_RELAY_URL} from "@welshman/net"
|
import {LOCAL_RELAY_URL} from "@welshman/net"
|
||||||
import {goto} from "$app/navigation"
|
import {goto} from "$app/navigation"
|
||||||
import {decodePubkey} from "@lib/util"
|
import {decodePubkey} from "@lib/util"
|
||||||
import Spinner from "@lib/components/Spinner.svelte"
|
import Spinner from "@lib/components/Spinner.svelte"
|
||||||
import {network} from "@app/core"
|
import {network} from "@app/core"
|
||||||
import {goToEvent, makeProfilePath} from "@app/routes"
|
import {goToEvent, goToNote, makeProfilePath} from "@app/routes"
|
||||||
import type {PageProps} from "./$types"
|
import type {PageProps} from "./$types"
|
||||||
|
|
||||||
const {params}: PageProps = $props()
|
const {params}: PageProps = $props()
|
||||||
|
|
@ -35,7 +35,12 @@
|
||||||
filters: getIdFilters([type === "nevent" ? data.id : Address.fromNaddr(bech32).toString()]),
|
filters: getIdFilters([type === "nevent" ? data.id : Address.fromNaddr(bech32).toString()]),
|
||||||
onEvent: (event: TrustedEvent) => {
|
onEvent: (event: TrustedEvent) => {
|
||||||
found = true
|
found = true
|
||||||
goToEvent(event, {replaceState: true})
|
|
||||||
|
if (event.kind === NOTE) {
|
||||||
|
goToNote({id: event.id, pubkey: event.pubkey, relays: data.relays})
|
||||||
|
} else {
|
||||||
|
goToEvent(event, {replaceState: true})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onClose: () => {
|
onClose: () => {
|
||||||
if (!found) {
|
if (!found) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import type {LayoutProps} from "./$types"
|
|
||||||
|
|
||||||
const {children, params}: LayoutProps = $props()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#key params.nevent}
|
|
||||||
{@render children?.()}
|
|
||||||
{/key}
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {onMount} from "svelte"
|
import {onMount} from "svelte"
|
||||||
import NotePage from "@app/components/NotePage.svelte"
|
import Spinner from "@lib/components/Spinner.svelte"
|
||||||
import {navigate} from "@app/modal"
|
import {goToHome, goToNote} from "@app/routes"
|
||||||
import {decodeNotePointer} from "@app/social"
|
import {decodeNotePointer} from "@app/social"
|
||||||
import type {PageProps} from "./$types"
|
import type {PageProps} from "./$types"
|
||||||
|
|
||||||
|
|
@ -10,12 +10,12 @@
|
||||||
const pointer = decodeNotePointer(params.nevent)
|
const pointer = decodeNotePointer(params.nevent)
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (!pointer) {
|
if (pointer) {
|
||||||
navigate("/", {replaceState: true})
|
goToNote(pointer)
|
||||||
|
} else {
|
||||||
|
goToHome()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if pointer}
|
<Spinner />
|
||||||
<NotePage {pointer} />
|
|
||||||
{/if}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue