Small route utils refactor

This commit is contained in:
Jon Staab 2026-08-14 08:47:36 -07:00
parent d23a6f6b75
commit 50554ec479
6 changed files with 65 additions and 100 deletions

View file

@ -10,7 +10,7 @@
formatTimestampAsDate,
} from "@welshman/lib"
import type {TrustedEvent, EventContent} from "@welshman/util"
import {MESSAGE, COMMENT, matchTag, tagSpec, tagValue} from "@welshman/util"
import {MESSAGE, COMMENT, getIdOrAddress, matchTag, tagSpec, tagValue} from "@welshman/util"
import {isMobile} from "@lib/html"
import Pen from "@assets/icons/pen.svg?dataurl"
import Reply from "@assets/icons/reply-2.svg?dataurl"
@ -33,7 +33,7 @@
import {colors} from "@app/theme"
import {ENABLE_ZAPS} from "@app/env"
import {deriveEvent, deriveEventsForUrl} from "@app/repository"
import {getRoomItemPath} from "@app/routes"
import {makeContentPath} from "@app/routes"
import {pushModal} from "@app/modal"
type Props = {
@ -47,7 +47,7 @@
const {url, event, replyTo = undefined, showPubkey = false, canEdit, onEdit}: Props = $props()
const path = getRoomItemPath(url, event)
const path = makeContentPath(url, event.kind, getIdOrAddress(event))
const h = tagValue(tagSpec("h"), event.tags)
const today = formatTimestampAsDate(now())
const profileDisplay = $profiles.display(event.pubkey, [url]).$

View file

@ -1,14 +1,14 @@
<script lang="ts">
import cx from "classnames"
import type {ComponentProps} from "svelte"
import {MESSAGE} from "@welshman/util"
import {MESSAGE, getIdOrAddress} from "@welshman/util"
import {isMobile} from "@lib/html"
import Link from "@lib/components/Link.svelte"
import NoteContent from "@app/components/NoteContent.svelte"
import {getRoomItemPath} from "@app/routes"
import {makeContentPath} from "@app/routes"
const props: ComponentProps<typeof NoteContent> = $props()
const path = getRoomItemPath(props.url!, props.event)
const path = makeContentPath(props.url!, props.event.kind, getIdOrAddress(props.event))
const minLength = 5000
const maxLength = 5500

View file

@ -1,7 +1,7 @@
<script lang="ts">
import type {NativeEmoji} from "emoji-picker-element/shared"
import type {TrustedEvent} from "@welshman/util"
import {tagSpec, tagValue} from "@welshman/util"
import {getIdOrAddress, tagSpec, tagValue} from "@welshman/util"
import Bolt from "@assets/icons/bolt.svg?dataurl"
import Reply from "@assets/icons/reply-2.svg?dataurl"
import Code2 from "@assets/icons/code-2.svg?dataurl"
@ -21,7 +21,7 @@
import {reactions, relays, roomPinLists, user} from "@app/core"
import {ROOM, deriveUserIsRoomAdmin} from "@app/rooms"
import {ENABLE_ZAPS} from "@app/env"
import {getRoomItemPath} from "@app/routes"
import {makeContentPath} from "@app/routes"
import {pushModal} from "@app/modal"
import {pushToast} from "@app/toast"
@ -34,7 +34,7 @@
const {url, event, reply}: Props = $props()
const h = tagValue(tagSpec(ROOM), event.tags) ?? ""
const path = getRoomItemPath(url, event)
const path = makeContentPath(url, event.kind, getIdOrAddress(event))
const pinIds = $roomPinLists.pins(url, h).$
const userIsRoomAdmin = deriveUserIsRoomAdmin(url, h)
const isPinned = $derived($pinIds.includes(event.id))

View file

@ -22,7 +22,7 @@ import {
makeRoomPath,
makeSpaceChatPath,
makeChatPath,
getContentPath,
makeContentPath,
} from "@app/routes"
import {CONTENT_KINDS, makeCommentFilter} from "@app/content"
import {notificationSettings} from "@app/settings"
@ -207,8 +207,8 @@ const latestEventByContentPath = (url: string, events: TrustedEvent[]) => {
if (!target) continue
const path = getContentPath(url, target.kind, target.idOrAddress)
const listPath = getContentPath(url, target.kind)
const path = makeContentPath(url, target.kind, target.idOrAddress)
const listPath = makeContentPath(url, target.kind)
if (path && listPath && !byPath.has(path)) {
byPath.set(path, {listPath, latestEvent: event})

View file

@ -25,7 +25,7 @@ import {User} from "@welshman/app"
import {app, messagingRelayLists, network, roomLists} from "@app/core"
import {DM_KINDS, CONTENT_KINDS, makeCommentFilter} from "@app/content"
import {notificationSettings, shouldNotify, userSettingsValues} from "@app/settings"
import {getEventPath, goToSpace} from "@app/routes"
import {makeEventPath, goToSpace} from "@app/routes"
export type PushSubscription = {
key: string
@ -110,7 +110,7 @@ export const onPushNotificationAction = async (action: ActionPerformed) => {
})
if (event) {
goto(await getEventPath(event, [relay]))
goto(await makeEventPath(event, [relay]))
} else {
goToSpace(relay)
}

View file

@ -13,7 +13,6 @@ import {
POLL,
THREAD,
ZAP_GOAL,
getAddress,
getIdOrAddress,
hexTags,
tagSpec,
@ -139,8 +138,7 @@ export const makePollPath = (url: string, id?: string) => makeSpacePath(url, "po
export const makeLibraryPath = (url: string, address?: string) =>
makeSpacePath(url, "library", address)
/** Path to a content item by kind, or to its listing when `idOrAddress` is omitted. */
export const getContentPath = (url: string, kind: number, idOrAddress?: string) => {
export const makeContentPath = (url: string, kind: number, idOrAddress?: string) => {
switch (kind) {
case ZAP_GOAL:
return makeGoalPath(url, idOrAddress)
@ -157,6 +155,55 @@ export const getContentPath = (url: string, kind: number, idOrAddress?: string)
}
}
export const makeEventPath = (event: TrustedEvent, urls: string[]) => {
if (DM_KINDS.includes(event.kind)) {
return makeChatPath([event.pubkey, ...tagValues(hexTags("p"), event.tags)])
}
if (urls.length > 0) {
const url = urls[0]
if (event.kind === MESSAGE) {
return makeMessagePath(url, event)
}
const path = makeContentPath(url, event.kind, getIdOrAddress(event))
if (path) {
return path
}
const parentKind = tagValue(tagSpec("K"), event.tags)
const parentIdOrAddress =
tagValue(tagSpec("A"), event.tags) ?? tagValue(tagSpec("E"), event.tags)
if (parentKind && parentIdOrAddress) {
if (parseInt(parentKind) === MESSAGE) {
return makeMessagePath(url, event)
}
const parentPath = makeContentPath(url, parseInt(parentKind), parentIdOrAddress)
if (parentPath) {
return parentPath
}
}
}
return entityLink(nip19.neventEncode({id: event.id, relays: urls}))
}
export const makeEventPermalink = (event: TrustedEvent, url?: string) => {
const urls = url ? [url] : Array.from(app.get().tracker.getRelays(event.id))
const path = makeEventPath(event, urls)
if (path.includes("://")) {
return path
}
return `${PLATFORM_URL}${path}#${nip19.neventEncode({id: event.id, relays: urls})}`
}
export const scrollToEvent = (id: string) => {
const element = document.querySelector(`[data-event="${id}"]`) as any
@ -178,7 +225,7 @@ export const scrollToEvent = (id: string) => {
export const goToEvent = (event: TrustedEvent, options: Record<string, any> = {}) => {
const urls = Array.from(app.get().tracker.getRelays(event.id))
const path = getEventPath(event, urls)
const path = makeEventPath(event, urls)
if (path.includes("://")) {
window.open(path)
@ -188,85 +235,3 @@ export const goToEvent = (event: TrustedEvent, options: Record<string, any> = {}
goto(path, {replaceState, ...options})
}
}
export const getEventPath = (event: TrustedEvent, urls: string[]) => {
if (DM_KINDS.includes(event.kind)) {
return makeChatPath([event.pubkey, ...tagValues(hexTags("p"), event.tags)])
}
if (urls.length > 0) {
const url = urls[0]
if (event.kind === ZAP_GOAL) {
return makeGoalPath(url, event.id)
}
if (event.kind === THREAD) {
return makeThreadPath(url, event.id)
}
if (event.kind === CLASSIFIED) {
return makeClassifiedPath(url, getAddress(event))
}
if (event.kind === EVENT_TIME) {
return makeCalendarPath(url, getAddress(event))
}
if (event.kind === PINBOARD) {
return makeLibraryPath(url, getAddress(event))
}
if (event.kind === POLL) {
return makePollPath(url, event.id)
}
if (event.kind === MESSAGE) {
return makeMessagePath(url, event)
}
const address = tagValue(tagSpec("A"), event.tags)
const kind = tagValue(tagSpec("K"), event.tags)
const id = tagValue(tagSpec("E"), event.tags)
if (id && kind) {
if (parseInt(kind) === ZAP_GOAL) {
return makeGoalPath(url, id)
}
if (parseInt(kind) === THREAD) {
return makeThreadPath(url, id)
}
if (parseInt(kind) === MESSAGE) {
return makeMessagePath(url, event)
}
}
if (address && kind) {
if (parseInt(kind) === CLASSIFIED) {
return makeClassifiedPath(url, address)
}
if (parseInt(kind) === EVENT_TIME) {
return makeCalendarPath(url, address)
}
}
}
return entityLink(nip19.neventEncode({id: event.id, relays: urls}))
}
export const makeEventPermalink = (event: TrustedEvent, url?: string) => {
const urls = url ? [url] : Array.from(app.get().tracker.getRelays(event.id))
const path = getEventPath(event, urls)
if (path.includes("://")) {
return path
}
return `${PLATFORM_URL}${path}#${nip19.neventEncode({id: event.id, relays: urls})}`
}
export const getRoomItemPath = (url: string, event: TrustedEvent) =>
getContentPath(url, event.kind, getIdOrAddress(event))