Flesh out people tab

This commit is contained in:
Jon Staab
2024-10-01 14:55:33 -07:00
parent 3e06c36563
commit 65b699d49d
11 changed files with 228 additions and 52 deletions
+12 -14
View File
@@ -17,7 +17,6 @@
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'
@@ -32,7 +31,7 @@
export let minLength = 500
export let maxLength = 700
export let showEntire = false
export let skipMedia = false
export let hideMedia = false
export let expandable = true
export let depth = 0
@@ -65,14 +64,11 @@
$: shortContent = showEntire
? fullContent
: truncate(
fullContent.filter(p => !skipMedia || (isLink(p) && p.value.isMedia)),
{
minLength,
maxLength,
mediaLength: 200,
},
)
: truncate(fullContent, {
minLength,
maxLength,
mediaLength: hideMedia ? 20 : 200,
})
$: ellipsize = expandable && shortContent.find(isEllipsis)
</script>
@@ -90,7 +86,7 @@
{:else if isCashu(parsed) || isInvoice(parsed)}
<ContentToken value={parsed.value} />
{:else if isLink(parsed)}
{#if isStartOrEnd(i)}
{#if isStartOrEnd(i) && !hideMedia}
<ContentLinkBlock value={parsed.value} />
{:else}
<ContentLinkInline value={parsed.value} />
@@ -98,10 +94,10 @@
{:else if isProfile(parsed)}
<ContentMention value={parsed.value} />
{:else if isEvent(parsed) || isAddress(parsed)}
{#if isStartOrEnd(i) && depth < 2}
{#if isStartOrEnd(i) && depth < 2 && !hideMedia}
<ContentQuote value={parsed.value} {depth}>
<div slot="note-content" let:event>
<svelte:self {event} depth={depth + 1} />
<svelte:self {hideMedia} {event} depth={depth + 1} />
</div>
</ContentQuote>
{:else}
@@ -120,6 +116,8 @@
{#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>
<button type="button" class="btn" on:click|stopPropagation|preventDefault={expand}>
See more
</button>
</div>
{/if}
+11 -4
View File
@@ -1,5 +1,6 @@
<script lang="ts">
import {getAddress, Address} from "@welshman/util"
import Spinner from "@lib/components/Spinner.svelte"
import NoteCard from "@app/components/NoteCard.svelte"
import {deriveEvent} from "@app/state"
@@ -14,8 +15,14 @@
$: 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 class="text-left my-2 max-w-full" on:click|stopPropagation>
{#if $event}
<NoteCard event={$event} class="p-4 rounded-box bg-base-300">
<slot name="note-content" event={$event} {depth} />
</NoteCard>
{:else}
<div class="p-4 rounded-box bg-base-300">
<Spinner loading>Loading event...</Spinner>
</div>
{/if}
</button>
+56
View File
@@ -0,0 +1,56 @@
<script lang="ts">
import {onMount} from 'svelte'
import {nip19} from 'nostr-tools'
import {ago, append, first, sortBy, max, WEEK, ctx} from '@welshman/lib'
import {NOTE, getAncestorTags, getListValues} from '@welshman/util'
import type {Filter} from '@welshman/util'
import {deriveEvents} from '@welshman/store'
import {repository, load, loadRelaySelections, userFollows, formatTimestamp, formatTimestampRelative} from '@welshman/app'
import Link from '@lib/components/Link.svelte'
import Profile from "@app/components/Profile.svelte"
import ProfileInfo from "@app/components/ProfileInfo.svelte"
import Content from "@app/components/Content.svelte"
import {entityLink} from '@app/state'
export let pubkey
const filters: Filter[] = [{kinds: [NOTE], authors: [pubkey], since: ago(WEEK)}]
const events = deriveEvents(repository, {filters})
$: roots = $events.filter(e => getAncestorTags(e.tags).replies.length === 0)
onMount(async () => {
// Make sure we have their relay selections before we load their posts
await loadRelaySelections(pubkey)
// Load at least one note, regardless of time frame
load({
filters: append({kinds: [NOTE], authors: [pubkey], limit: 1}, filters),
relays: ctx.app.router.FromPubkeys([pubkey]).getUrls(),
})
})
</script>
<div class="card bg-base-100 shadow-xl">
<div class="card-body">
<Profile {pubkey} />
<ProfileInfo {pubkey} />
{#if roots.length > 0}
{@const event = first(sortBy(e => -e.created_at, roots))}
{@const relays = ctx.app.router.Event(event).getUrls()}
{@const nevent = nip19.neventEncode({id: event.id, relays})}
{@const following = getListValues("p", $userFollows).includes(pubkey)}
<div class="divider" />
<Link external class="chat chat-start" href={entityLink(nevent)}>
<div class="chat-bubble">
<Content hideMedia={!following} {event} />
<p class="text-xs text-right">{formatTimestamp(event.created_at)}</p>
</div>
</Link>
<div class="flex gap-2">
<div class="badge badge-neutral">{roots.length} recent {roots.length === 1 ? 'note' : 'notes'}</div>
<div class="badge badge-neutral">Last posted {formatTimestampRelative(event.created_at)}</div>
</div>
{/if}
</div>
</div>
+19 -7
View File
@@ -1,22 +1,34 @@
<script lang="ts">
import {displayPubkey} from "@welshman/util"
import {deriveProfile, deriveHandleForPubkey, displayHandle, deriveProfileDisplay, formatTimestamp} from "@welshman/app"
import {nip19} from 'nostr-tools'
import {derived} from 'svelte/store'
import {displayPubkey, getListValues} from "@welshman/util"
import {userFollows, deriveUserWotScore, deriveProfile, deriveHandleForPubkey, displayHandle, deriveProfileDisplay, formatTimestamp, getUserWotScore, followsByPubkey} from "@welshman/app"
import Link from "@lib/components/Link.svelte"
import Avatar from "@lib/components/Avatar.svelte"
import WotScore from "@lib/components/WotScore.svelte"
import {entityLink} from '@app/state'
export let pubkey
const npub = nip19.npubEncode(pubkey)
const profile = deriveProfile(pubkey)
const profileDisplay = deriveProfileDisplay(pubkey)
const handle = deriveHandleForPubkey(pubkey)
const score = deriveUserWotScore(pubkey)
$: following = getListValues("p", $userFollows).includes(pubkey)
</script>
<div class="flex gap-2 max-w-full">
<div class="py-1">
<div class="flex gap-3 max-w-full">
<Link external href={entityLink(npub)} class="py-1">
<Avatar src={$profile?.picture} size={10} />
</div>
</Link>
<div class="flex flex-col min-w-0">
<div class="text-bold text-ellipsis overflow-hidden">
{$profileDisplay}
<div class="flex gap-2 items-center">
<Link external class="text-bold text-ellipsis overflow-hidden" href={entityLink(npub)}>
{$profileDisplay}
</Link>
<WotScore score={$score} active={following} />
</div>
<div class="text-sm opacity-75 text-ellipsis overflow-hidden">
{$handle ? displayHandle($handle) : displayPubkey(pubkey)}
+12
View File
@@ -0,0 +1,12 @@
<script lang="ts">
import {deriveProfile} from "@welshman/app"
import Content from "@app/components/Content.svelte"
export let pubkey
const profile = deriveProfile(pubkey)
</script>
{#if $profile}
<Content event={{content: $profile.about, tags: []}} hideMedia />
{/if}