Add render support
This commit is contained in:
Generated
+15
@@ -24,6 +24,7 @@
|
|||||||
"@tiptap/suggestion": "^2.6.4",
|
"@tiptap/suggestion": "^2.6.4",
|
||||||
"@types/throttle-debounce": "^5.0.2",
|
"@types/throttle-debounce": "^5.0.2",
|
||||||
"@welshman/app": "^0.0.7",
|
"@welshman/app": "^0.0.7",
|
||||||
|
"@welshman/content": "^0.0.9",
|
||||||
"@welshman/lib": "^0.0.17",
|
"@welshman/lib": "^0.0.17",
|
||||||
"@welshman/net": "^0.0.22",
|
"@welshman/net": "^0.0.22",
|
||||||
"@welshman/signer": "^0.0.5",
|
"@welshman/signer": "^0.0.5",
|
||||||
@@ -85,6 +86,11 @@
|
|||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@braintree/sanitize-url": {
|
||||||
|
"version": "7.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.0.tgz",
|
||||||
|
"integrity": "sha512-o+UlMLt49RvtCASlOMW0AkHnabN9wR9rwCCherxO0yG4Npy34GkvrAqdXQvrhNs+jh+gkK8gB8Lf05qL/O7KWg=="
|
||||||
|
},
|
||||||
"node_modules/@esbuild/aix-ppc64": {
|
"node_modules/@esbuild/aix-ppc64": {
|
||||||
"version": "0.21.5",
|
"version": "0.21.5",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
|
||||||
@@ -1679,6 +1685,15 @@
|
|||||||
"nostr-tools": "^2.7.2"
|
"nostr-tools": "^2.7.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@welshman/content": {
|
||||||
|
"version": "0.0.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@welshman/content/-/content-0.0.9.tgz",
|
||||||
|
"integrity": "sha512-tmzSRvVmOdet+X9W1vmjqHf4tkyhxotZ0qG7+iVPd7SjRSvuDmq09odT19rQtWn5Pl8mmEREyQgqzTRubDbsxg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@braintree/sanitize-url": "^7.0.2",
|
||||||
|
"nostr-tools": "^2.7.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@welshman/lib": {
|
"node_modules/@welshman/lib": {
|
||||||
"version": "0.0.17",
|
"version": "0.0.17",
|
||||||
"resolved": "https://registry.npmjs.org/@welshman/lib/-/lib-0.0.17.tgz",
|
"resolved": "https://registry.npmjs.org/@welshman/lib/-/lib-0.0.17.tgz",
|
||||||
|
|||||||
@@ -49,6 +49,7 @@
|
|||||||
"@tiptap/suggestion": "^2.6.4",
|
"@tiptap/suggestion": "^2.6.4",
|
||||||
"@types/throttle-debounce": "^5.0.2",
|
"@types/throttle-debounce": "^5.0.2",
|
||||||
"@welshman/app": "^0.0.7",
|
"@welshman/app": "^0.0.7",
|
||||||
|
"@welshman/content": "^0.0.9",
|
||||||
"@welshman/lib": "^0.0.17",
|
"@welshman/lib": "^0.0.17",
|
||||||
"@welshman/net": "^0.0.22",
|
"@welshman/net": "^0.0.22",
|
||||||
"@welshman/signer": "^0.0.5",
|
"@welshman/signer": "^0.0.5",
|
||||||
|
|||||||
@@ -0,0 +1,125 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {fromNostrURI} from "@welshman/util"
|
||||||
|
import {
|
||||||
|
parse,
|
||||||
|
truncate,
|
||||||
|
render as renderParsed,
|
||||||
|
isText,
|
||||||
|
isTopic,
|
||||||
|
isCode,
|
||||||
|
isCashu,
|
||||||
|
isInvoice,
|
||||||
|
isLink,
|
||||||
|
isProfile,
|
||||||
|
isEvent,
|
||||||
|
isEllipsis,
|
||||||
|
isAddress,
|
||||||
|
isNewline,
|
||||||
|
} from "@welshman/content"
|
||||||
|
import Link from '@lib/components/Link.svelte'
|
||||||
|
import Button from '@lib/components/Button.svelte'
|
||||||
|
import ContentToken from '@app/components/ContentToken.svelte'
|
||||||
|
import ContentCode from '@app/components/ContentCode.svelte'
|
||||||
|
import ContentLinkInline from '@app/components/ContentLinkInline.svelte'
|
||||||
|
import ContentLinkBlock from '@app/components/ContentLinkBlock.svelte'
|
||||||
|
import ContentNewline from '@app/components/ContentNewline.svelte'
|
||||||
|
import ContentQuote from '@app/components/ContentQuote.svelte'
|
||||||
|
import ContentTopic from '@app/components/ContentTopic.svelte'
|
||||||
|
import ContentMention from '@app/components/ContentMention.svelte'
|
||||||
|
import {nostr} from '@app/state'
|
||||||
|
|
||||||
|
export let event
|
||||||
|
export let minLength = 500
|
||||||
|
export let maxLength = 700
|
||||||
|
export let showEntire = false
|
||||||
|
export let skipMedia = false
|
||||||
|
export let expandable = true
|
||||||
|
export let depth = 0
|
||||||
|
|
||||||
|
const fullContent = parse(event)
|
||||||
|
|
||||||
|
const expand = () => {
|
||||||
|
showEntire = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const isBoundary = (i: number) => {
|
||||||
|
const parsed = fullContent[i]
|
||||||
|
|
||||||
|
if (!parsed || isNewline(parsed)) return true
|
||||||
|
if (isText(parsed)) return parsed.value.match(/^\s+$/)
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const isStartAndEnd = (i: number) => Boolean(isBoundary(i - 1) && isBoundary(i + 1))
|
||||||
|
|
||||||
|
const isStartOrEnd = (i: number) => Boolean(isBoundary(i - 1) || isBoundary(i + 1))
|
||||||
|
|
||||||
|
const isBlock = (i: number) => {
|
||||||
|
const parsed = fullContent[i]
|
||||||
|
|
||||||
|
return isEvent(parsed) || isAddress(parsed) || isLink(parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
const isNextToBlock = (i: number) => isBlock(i - 1) || isBlock(i + 1)
|
||||||
|
|
||||||
|
$: shortContent = showEntire
|
||||||
|
? fullContent
|
||||||
|
: truncate(
|
||||||
|
fullContent.filter(p => !skipMedia || (isLink(p) && p.value.isMedia)),
|
||||||
|
{
|
||||||
|
minLength,
|
||||||
|
maxLength,
|
||||||
|
mediaLength: 200,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
$: ellipsize = expandable && shortContent.find(isEllipsis)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="overflow-hidden text-ellipsis"
|
||||||
|
style={ellipsize ? "mask-image: linear-gradient(0deg, transparent 0px, black 100px)" : ""}>
|
||||||
|
{#each shortContent as parsed, i}
|
||||||
|
{#if isNewline(parsed)}
|
||||||
|
<ContentNewline value={parsed.value.slice(isNextToBlock(i) ? 1 : 0)} />
|
||||||
|
{:else if isTopic(parsed)}
|
||||||
|
<ContentTopic value={parsed.value} />
|
||||||
|
{:else if isCode(parsed)}
|
||||||
|
<ContentCode value={parsed.value} />
|
||||||
|
{:else if isCashu(parsed) || isInvoice(parsed)}
|
||||||
|
<ContentToken value={parsed.value} />
|
||||||
|
{:else if isLink(parsed)}
|
||||||
|
{#if isStartOrEnd(i)}
|
||||||
|
<ContentLinkBlock value={parsed.value} />
|
||||||
|
{:else}
|
||||||
|
<ContentLinkInline value={parsed.value} />
|
||||||
|
{/if}
|
||||||
|
{:else if isProfile(parsed)}
|
||||||
|
<ContentMention value={parsed.value} />
|
||||||
|
{:else if isEvent(parsed) || isAddress(parsed)}
|
||||||
|
{#if isStartOrEnd(i) && depth < 2}
|
||||||
|
<ContentQuote value={parsed.value} {depth}>
|
||||||
|
<div slot="note-content" let:event>
|
||||||
|
<svelte:self {event} depth={depth + 1} />
|
||||||
|
</div>
|
||||||
|
</ContentQuote>
|
||||||
|
{:else}
|
||||||
|
<Link
|
||||||
|
external
|
||||||
|
class="overflow-hidden text-ellipsis whitespace-nowrap underline"
|
||||||
|
href={nostr(parsed.raw)}>
|
||||||
|
{fromNostrURI(parsed.raw).slice(0, 16) + "…"}
|
||||||
|
</Link>
|
||||||
|
{/if}
|
||||||
|
{:else}
|
||||||
|
{@html renderParsed(parsed)}
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if ellipsize}
|
||||||
|
<div class="z-feature relative -mt-24 mb-0 flex justify-center bg-gradient-to-t from-base-100 pt-12" class:-ml-12={depth > 0}>
|
||||||
|
<Button class="btn" on:click={expand}>See more</Button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let value
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<code class="link-content block w-full">
|
||||||
|
{value}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {ellipsize, displayUrl, postJson} from "@welshman/lib"
|
||||||
|
import {dufflepud, imgproxy} from "@app/state"
|
||||||
|
import Link from "@lib/components/Link.svelte"
|
||||||
|
|
||||||
|
export let value
|
||||||
|
|
||||||
|
const url = value.url.toString()
|
||||||
|
|
||||||
|
const loadPreview = async () => {
|
||||||
|
const json = await postJson(dufflepud("link/preview"), {url})
|
||||||
|
|
||||||
|
if (!json?.title && !json?.image) {
|
||||||
|
throw new Error("Failed to load link preview")
|
||||||
|
}
|
||||||
|
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Link
|
||||||
|
external
|
||||||
|
href={url}
|
||||||
|
style="background-color: rgba(15, 15, 14, 0.5)"
|
||||||
|
class="relative flex w-full flex-grow flex-col overflow-hidden rounded-xl my-2">
|
||||||
|
{#if url.match(/\.(mov|webm|mp4)$/)}
|
||||||
|
<video controls src={url} class="max-h-96 object-contain object-center">
|
||||||
|
<track kind="captions" />
|
||||||
|
</video>
|
||||||
|
{:else if url.match(/\.(jpe?g|png|gif|webp)$/)}
|
||||||
|
<img
|
||||||
|
alt="Link preview"
|
||||||
|
src={imgproxy(url)}
|
||||||
|
class="object-cover object-center max-h-96" />
|
||||||
|
{:else}
|
||||||
|
{#await loadPreview()}
|
||||||
|
<span class="loading loading-spinner" />
|
||||||
|
{:then preview}
|
||||||
|
{#if preview.image}
|
||||||
|
<img
|
||||||
|
alt="Link preview"
|
||||||
|
src={imgproxy(preview.image)}
|
||||||
|
class="max-h-96 object-contain object-center" />
|
||||||
|
{/if}
|
||||||
|
<div class="h-px bg-neutral-600" />
|
||||||
|
{#if preview.title}
|
||||||
|
<div class="flex flex-col bg-white px-4 py-2 text-black">
|
||||||
|
<strong class="overflow-hidden text-ellipsis whitespace-nowrap">{preview.title}</strong>
|
||||||
|
<small>{ellipsize(preview.description, 140)}</small>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/await}
|
||||||
|
{/if}
|
||||||
|
</Link>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {displayUrl} from "@welshman/lib"
|
||||||
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
|
import Link from "@lib/components/Link.svelte"
|
||||||
|
|
||||||
|
export let value
|
||||||
|
|
||||||
|
const url = value.url.toString()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Link external href={url} class="link-content">
|
||||||
|
<Icon icon="link-round" size={3} class="inline-block" />
|
||||||
|
{displayUrl(url)}
|
||||||
|
</Link>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {nip19} from 'nostr-tools'
|
||||||
|
import {displayProfile} from "@welshman/util"
|
||||||
|
import {deriveProfile} from "@welshman/app"
|
||||||
|
import Link from "@lib/components/Link.svelte"
|
||||||
|
import {nostr} from '@app/state'
|
||||||
|
|
||||||
|
export let value
|
||||||
|
|
||||||
|
const profile = deriveProfile(value.pubkey)
|
||||||
|
const nprofile = nip19.nprofileEncode(value)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Link external href={nostr(nprofile)} class="link-content">
|
||||||
|
@{displayProfile($profile)}
|
||||||
|
</Link>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let value
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#each value as _}
|
||||||
|
<br />
|
||||||
|
{/each}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {getAddress, Address} from "@welshman/util"
|
||||||
|
import NoteCard from "@app/components/NoteCard.svelte"
|
||||||
|
import {deriveEvent} from "@app/state"
|
||||||
|
|
||||||
|
export let value
|
||||||
|
export let depth = 0
|
||||||
|
|
||||||
|
const {id, identifier, kind, pubkey, relays} = value
|
||||||
|
const idOrAddress = id || new Address(kind, pubkey, identifier).toString()
|
||||||
|
const event = deriveEvent(idOrAddress, relays)
|
||||||
|
|
||||||
|
$: address = $event ? getAddress($event) : ""
|
||||||
|
$: isGroup = address.match(/^(34550|35834):/)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button class="text-left my-2" on:click|stopPropagation>
|
||||||
|
<NoteCard event={$event} class="p-4 rounded-box bg-base-300">
|
||||||
|
<slot name="note-content" event={$event} {depth} />
|
||||||
|
</NoteCard>
|
||||||
|
</button>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import cx from "classnames"
|
||||||
|
import type {NodeViewProps} from "@tiptap/core"
|
||||||
|
import {NodeViewWrapper} from "svelte-tiptap"
|
||||||
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
|
import Button from "@lib/components/Button.svelte"
|
||||||
|
import {clip} from "@app/toast"
|
||||||
|
|
||||||
|
export let value
|
||||||
|
|
||||||
|
const copy = () => clip(value)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Button on:click={copy} class="link-content">
|
||||||
|
<Icon icon="bolt" size={3} class="inline-block translate-y-px" />
|
||||||
|
{value.slice(0, 16)}...
|
||||||
|
</Button>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let value
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<span class="link-content">
|
||||||
|
#{value}
|
||||||
|
</span>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {displayPubkey} from "@welshman/util"
|
||||||
|
import {deriveProfile, deriveProfileDisplay, formatTimestamp} from "@welshman/app"
|
||||||
|
import Avatar from "@lib/components/Avatar.svelte"
|
||||||
|
import Profile from "@app/components/Profile.svelte"
|
||||||
|
|
||||||
|
export let event
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-2 {$$props.class}">
|
||||||
|
<div class="flex justify-between gap-2">
|
||||||
|
<Profile pubkey={event.pubkey} />
|
||||||
|
<span class="text-sm opacity-75">{formatTimestamp(event.created_at)}</span>
|
||||||
|
</div>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {displayPubkey} from "@welshman/util"
|
||||||
|
import {deriveProfile, deriveProfileDisplay, formatTimestamp} from "@welshman/app"
|
||||||
|
import Avatar from "@lib/components/Avatar.svelte"
|
||||||
|
|
||||||
|
export let pubkey
|
||||||
|
|
||||||
|
const profile = deriveProfile(pubkey)
|
||||||
|
const profileDisplay = deriveProfileDisplay(pubkey)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<div class="py-1">
|
||||||
|
<Avatar src={$profile?.picture} size={10} />
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<div class="text-bold">{$profileDisplay}</div>
|
||||||
|
<div class="text-sm opacity-75">{displayPubkey(pubkey)}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -1,31 +1,17 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {displayPubkey} from "@welshman/util"
|
import Content from "@app/components/Content.svelte"
|
||||||
import {deriveProfile, deriveProfileDisplay, formatTimestamp} from "@welshman/app"
|
import NoteCard from "@app/components/NoteCard.svelte"
|
||||||
import Avatar from "@lib/components/Avatar.svelte"
|
|
||||||
|
|
||||||
export let root
|
export let root
|
||||||
export let replies
|
export let replies
|
||||||
|
|
||||||
const profile = deriveProfile(root.pubkey)
|
|
||||||
const profileDisplay = deriveProfileDisplay(root.pubkey)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="card2 flex flex-col gap-2">
|
<NoteCard event={root} class="card2">
|
||||||
<div class="flex items-center justify-between gap-2">
|
<div class="ml-12">
|
||||||
<div class="flex gap-2">
|
<Content event={root} />
|
||||||
<div class="py-1">
|
|
||||||
<Avatar src={$profile?.picture} size={10} />
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<div class="text-bold">{$profileDisplay}</div>
|
|
||||||
<div class="text-sm opacity-75">{displayPubkey(root.pubkey)}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span class="text-sm opacity-75">{formatTimestamp(root.created_at)}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-12"></div>
|
</NoteCard>
|
||||||
</div>
|
|
||||||
{#if replies.length > 0}
|
{#if replies.length > 0}
|
||||||
Show {replies.length} {replies.length === 1 ? "reply" : "replies"}
|
Show {replies.length} {replies.length === 1 ? "reply" : "replies"}
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -47,8 +47,28 @@ export const INDEXER_RELAYS = ["wss://purplepag.es/", "wss://relay.damus.io/", "
|
|||||||
|
|
||||||
export const DUFFLEPUD_URL = "https://dufflepud.onrender.com"
|
export const DUFFLEPUD_URL = "https://dufflepud.onrender.com"
|
||||||
|
|
||||||
|
export const IMGPROXY_URL = "https://imgproxy.coracle.social"
|
||||||
|
|
||||||
export const REACTION_KINDS = [REACTION, ZAP_RESPONSE]
|
export const REACTION_KINDS = [REACTION, ZAP_RESPONSE]
|
||||||
|
|
||||||
|
export const dufflepud = (path: string) => DUFFLEPUD_URL + '/' + path
|
||||||
|
|
||||||
|
export const imgproxy = (url: string, {w = 640, h = 1024} = {}) => {
|
||||||
|
if (!url || url.match("gif$")) {
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
|
||||||
|
url = url.split("?")[0]
|
||||||
|
|
||||||
|
try {
|
||||||
|
return url ? `${IMGPROXY_URL}/x/s:${w}:${h}/${btoa(url)}` : url
|
||||||
|
} catch (e) {
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const nostr = (entity: string) => `https://coracle.social/${entity}`
|
||||||
|
|
||||||
setContext({
|
setContext({
|
||||||
net: getDefaultNetContext(),
|
net: getDefaultNetContext(),
|
||||||
app: getDefaultAppContext({
|
app: getDefaultAppContext({
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
import {ellipsize} from "@welshman/lib"
|
import {ellipsize} from "@welshman/lib"
|
||||||
import {type TrustedEvent, fromNostrURI, Address} from "@welshman/util"
|
import {type TrustedEvent, fromNostrURI, Address} from "@welshman/util"
|
||||||
import Link from "@lib/components/Link.svelte"
|
import Link from "@lib/components/Link.svelte"
|
||||||
import {deriveEvent} from "@app/state"
|
import {deriveEvent, nostr} from "@app/state"
|
||||||
|
|
||||||
export let node: NodeViewProps["node"]
|
export let node: NodeViewProps["node"]
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<NodeViewWrapper class="inline">
|
<NodeViewWrapper class="inline">
|
||||||
<Link external href="https://njump.me/{node.attrs.nevent}" class="link-content">
|
<Link external href={nostr(node.attrs.nevent)} class="link-content">
|
||||||
{displayEvent($event)}
|
{displayEvent($event)}
|
||||||
</Link>
|
</Link>
|
||||||
</NodeViewWrapper>
|
</NodeViewWrapper>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
import {displayProfile} from "@welshman/util"
|
import {displayProfile} from "@welshman/util"
|
||||||
import {deriveProfile} from "@welshman/app"
|
import {deriveProfile} from "@welshman/app"
|
||||||
import Link from "@lib/components/Link.svelte"
|
import Link from "@lib/components/Link.svelte"
|
||||||
|
import {nostr} from '@app/state'
|
||||||
|
|
||||||
export let node: NodeViewProps["node"]
|
export let node: NodeViewProps["node"]
|
||||||
export let selected: NodeViewProps["selected"]
|
export let selected: NodeViewProps["selected"]
|
||||||
@@ -15,7 +16,7 @@
|
|||||||
<NodeViewWrapper class="inline">
|
<NodeViewWrapper class="inline">
|
||||||
<Link
|
<Link
|
||||||
external
|
external
|
||||||
href="https://njump.me/{node.attrs.nprofile}"
|
href={nostr(node.attrs.nprofile)}
|
||||||
class={cx("link-content", {"link-content-selected": selected})}>
|
class={cx("link-content", {"link-content-selected": selected})}>
|
||||||
@{displayProfile($profile)}
|
@{displayProfile($profile)}
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import Link from "@lib/components/Link.svelte"
|
import Link from "@lib/components/Link.svelte"
|
||||||
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 {nostr} from '@app/state'
|
||||||
|
|
||||||
const nprofile =
|
const nprofile =
|
||||||
"nprofile1qqsf03c2gsmx5ef4c9zmxvlew04gdh7u94afnknp33qvv3c94kvwxgspz4mhxue69uhhyetvv9ujuerpd46hxtnfduhsz9rhwden5te0wfjkcctev93xcefwdaexwtcpzdmhxue69uhhqatjwpkx2urpvuhx2ue0vamm57"
|
"nprofile1qqsf03c2gsmx5ef4c9zmxvlew04gdh7u94afnknp33qvv3c94kvwxgspz4mhxue69uhhyetvv9ujuerpd46hxtnfduhsz9rhwden5te0wfjkcctev93xcefwdaexwtcpzdmhxue69uhhqatjwpkx2urpvuhx2ue0vamm57"
|
||||||
@@ -33,7 +34,7 @@
|
|||||||
<p class="text-center">
|
<p class="text-center">
|
||||||
Built with 💜 by
|
Built with 💜 by
|
||||||
<span class="text-primary">
|
<span class="text-primary">
|
||||||
@<Link external href="https://njump.me/{nprofile}" class="link">hodlbod</Link>
|
@<Link external href={nostr(nprofile)} class="link">hodlbod</Link>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<div class="flex justify-center gap-4">
|
<div class="flex justify-center gap-4">
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
data-tip="Create an Event"
|
data-tip="Create an Event"
|
||||||
on:click={createThread}>
|
on:click={createThread}>
|
||||||
<div class="btn btn-circle btn-primary flex h-12 w-12 items-center justify-center">
|
<div class="btn btn-circle btn-primary flex h-12 w-12 items-center justify-center">
|
||||||
<Icon icon="add-square" />
|
<Icon icon="notes-minimalistic" />
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user