2025-11-14 19:35:19 +00:00
|
|
|
<script lang="ts">
|
|
|
|
|
import {formatTimestamp} from "@welshman/lib"
|
2026-07-28 16:16:26 +00:00
|
|
|
import {getIdFilters, matchTag, tagSpec} from "@welshman/util"
|
2026-08-13 21:44:41 +00:00
|
|
|
import {LOCAL_RELAY_URL} from "@welshman/net"
|
2025-11-14 19:35:19 +00:00
|
|
|
import type {TrustedEvent} from "@welshman/util"
|
2026-09-09 20:53:25 +00:00
|
|
|
import Cv from "@lib/components/Cv.svelte"
|
2025-11-14 19:35:19 +00:00
|
|
|
import Button from "@lib/components/Button.svelte"
|
2026-09-26 05:07:43 +00:00
|
|
|
import MenuButton from "@lib/components/MenuButton.svelte"
|
2025-11-14 19:35:19 +00:00
|
|
|
import Profile from "@app/components/Profile.svelte"
|
|
|
|
|
import ProfileName from "@app/components/ProfileName.svelte"
|
|
|
|
|
import ProfileDetail from "@app/components/ProfileDetail.svelte"
|
|
|
|
|
import NoteContent from "@app/components/NoteContent.svelte"
|
|
|
|
|
import ReportMenu from "@app/components/ReportMenu.svelte"
|
2026-08-13 21:44:41 +00:00
|
|
|
import {network} from "@app/core"
|
2026-06-08 21:14:40 +00:00
|
|
|
import {pushModal} from "@app/modal"
|
|
|
|
|
import {goToEvent} from "@app/routes"
|
2025-11-14 19:35:19 +00:00
|
|
|
|
|
|
|
|
type Props = {
|
|
|
|
|
url: string
|
|
|
|
|
event: TrustedEvent
|
2026-03-19 15:40:34 +00:00
|
|
|
onResolved?: () => void
|
2025-11-14 19:35:19 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-19 15:40:34 +00:00
|
|
|
const {url, event, onResolved}: Props = $props()
|
2025-11-14 19:35:19 +00:00
|
|
|
|
2026-07-28 16:16:26 +00:00
|
|
|
const etag = matchTag(tagSpec("e"), event.tags)
|
|
|
|
|
const ptag = matchTag(tagSpec("p"), event.tags)
|
2025-11-14 19:35:19 +00:00
|
|
|
const reason = etag?.[2] || ptag?.[2]
|
|
|
|
|
|
2026-09-26 08:12:13 +00:00
|
|
|
const onClick = (event: TrustedEvent) => (e: Event) => {
|
|
|
|
|
if (e.target instanceof Element && e.target.classList.contains("profile-name")) {
|
2025-11-14 19:35:19 +00:00
|
|
|
pushModal(ProfileDetail, {pubkey: event.pubkey, url})
|
|
|
|
|
} else {
|
|
|
|
|
goToEvent(event)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
2026-09-26 07:50:26 +00:00
|
|
|
<Cv class="card card-sm flex flex-col gap-4">
|
2025-11-14 19:35:19 +00:00
|
|
|
<div class="flex justify-between">
|
|
|
|
|
<div>
|
2026-02-13 21:05:17 +00:00
|
|
|
<ProfileName pubkey={event.pubkey} {url} />
|
2025-11-14 19:35:19 +00:00
|
|
|
<span>
|
|
|
|
|
Reported this event
|
|
|
|
|
{#if reason}
|
|
|
|
|
as "{reason}"
|
|
|
|
|
{/if}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
2026-09-26 05:07:43 +00:00
|
|
|
<MenuButton component={ReportMenu} componentProps={{url, event, onResolved}} />
|
2025-11-14 19:35:19 +00:00
|
|
|
</div>
|
|
|
|
|
{#if event.content}
|
2026-06-24 20:56:53 +00:00
|
|
|
<div class="border-l-2 pl-3" style="border-color: var(--primary)">
|
2025-11-14 19:35:19 +00:00
|
|
|
<NoteContent {event} />
|
|
|
|
|
</div>
|
|
|
|
|
{/if}
|
2026-06-24 20:56:53 +00:00
|
|
|
<div class="card card-sm">
|
2025-11-14 19:35:19 +00:00
|
|
|
{#if etag}
|
2026-09-21 17:58:14 +00:00
|
|
|
{#await $network.loadComplete( {relays: [url, LOCAL_RELAY_URL], filters: getIdFilters( [etag[1]], )}, )}
|
2025-11-14 19:35:19 +00:00
|
|
|
<p>Loading</p>
|
|
|
|
|
{:then reportedEvents}
|
|
|
|
|
{#if reportedEvents.length === 0}
|
|
|
|
|
<p>Unable to find reported note.</p>
|
|
|
|
|
{:else}
|
|
|
|
|
{@const event = reportedEvents[0]}
|
2026-09-26 08:12:13 +00:00
|
|
|
<Button class="flex flex-col gap-2 w-full" onclick={onClick(event)}>
|
2025-11-14 19:35:19 +00:00
|
|
|
<div class="flex items-center justify-between gap-2">
|
|
|
|
|
<span class="profile-name">
|
|
|
|
|
@<ProfileName pubkey={event.pubkey} {url} />
|
|
|
|
|
</span>
|
|
|
|
|
<span class="text-xs opacity-75">
|
|
|
|
|
{formatTimestamp(event.created_at)}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<NoteContent {event} />
|
|
|
|
|
</Button>
|
|
|
|
|
{/if}
|
|
|
|
|
{/await}
|
|
|
|
|
{:else if ptag}
|
|
|
|
|
<Profile pubkey={ptag[1]} />
|
|
|
|
|
{/if}
|
|
|
|
|
</div>
|
2026-09-09 20:53:25 +00:00
|
|
|
</Cv>
|