Show image link if image fails to load

This commit is contained in:
Jon Staab
2025-06-05 13:37:50 -07:00
parent 11aa841241
commit 45397e7fb8
6 changed files with 34 additions and 12 deletions
+1 -1
View File
@@ -31,7 +31,7 @@
</script>
<Link external href={url} class="my-2 block">
<div class="overflow-hidden rounded-box leading-[0]">
<div class="overflow-hidden rounded-box">
{#if url.match(/\.(mov|webm|mp4)$/)}
<video controls src={url} class="max-h-96 object-contain object-center">
<track kind="captions" />
@@ -1,7 +1,9 @@
<script lang="ts">
import {onMount, onDestroy} from "svelte"
import {displayUrl} from "@welshman/lib"
import {getTags, getTagValue, tagsFromIMeta} from "@welshman/util"
import {decryptFile} from "@welshman/editor"
import Icon from "@lib/components/Icon.svelte"
import {imgproxy} from "@app/state"
const {value, event, ...props} = $props()
@@ -16,6 +18,11 @@
const nonce = getTagValue("decryption-nonce", meta)
const encryptionAlgorithm = getTagValue("encryption-algorithm", meta)
const onError = () => {
hasError = true
}
let hasError = $state(false)
let src = $state(imgproxy(url))
onMount(async () => {
@@ -36,4 +43,11 @@
})
</script>
<img alt="" {src} {...props} />
{#if hasError}
<a href={url} class="link-content whitespace-nowrap">
<Icon icon="link-round" size={3} class="inline-block" />
{displayUrl(url)}
</a>
{:else}
<img alt="" {src} onerror={onError} {...props} />
{/if}
+5 -2
View File
@@ -10,6 +10,7 @@
import Button from "@lib/components/Button.svelte"
import ProfileSpaces from "@app/components/ProfileSpaces.svelte"
import {membershipsByPubkey} from "@app/state"
import {goToEvent} from "@app/routes"
import {pushModal} from "@app/modal"
type Props = {
@@ -23,6 +24,8 @@
const membership = $derived($membershipsByPubkey.get(pubkey))
const relays = $derived(getRelayTags(getListTags(membership)))
const viewEvent = () => goToEvent($events[0]!)
const openSpaces = () => pushModal(ProfileSpaces, {pubkey, url})
onMount(async () => {
@@ -42,9 +45,9 @@
<div class="flex flex-wrap gap-2">
{#if $events.length > 0}
<div class="badge badge-neutral">
<Button onclick={viewEvent} class="badge badge-neutral">
Last active {formatTimestampRelative($events[0].created_at)}
</div>
</Button>
{/if}
{#if relays.length > 0}
<Button onclick={openSpaces} class="badge badge-neutral">
@@ -1,6 +1,6 @@
<script lang="ts">
import {derived} from "svelte/store"
import {groupBy, first, last, uniq, avg, overlappingPairs} from "@welshman/lib"
import {groupBy, ago, MONTH, first, last, uniq, avg, overlappingPairs} from "@welshman/lib"
import {formatTimestamp} from "@welshman/lib"
import {MESSAGE, getTagValue} from "@welshman/util"
import type {TrustedEvent} from "@welshman/util"
@@ -17,8 +17,8 @@
}
const {url}: Props = $props()
const messages = deriveEventsForUrl(url, [{kinds: [MESSAGE]}])
const since = ago(MONTH)
const messages = deriveEventsForUrl(url, [{kinds: [MESSAGE], since}])
const conversations = derived(messages, $messages => {
const convs = []
+8 -3
View File
@@ -1,4 +1,5 @@
import type {Page} from "@sveltejs/kit"
import * as nip19 from "nostr-tools/nip19"
import {goto} from "$app/navigation"
import {nthEq, sleep} from "@welshman/lib"
import type {TrustedEvent} from "@welshman/util"
@@ -13,7 +14,7 @@ import {
THREAD,
EVENT_TIME,
} from "@welshman/util"
import {makeChatId, decodeRelay, encodeRelay, userRoomsByUrl, ROOM} from "@app/state"
import {makeChatId, entityLink, decodeRelay, encodeRelay, userRoomsByUrl, ROOM} from "@app/state"
export const makeSpacePath = (url: string, ...extra: (string | undefined)[]) => {
let path = `/spaces/${encodeRelay(url)}`
@@ -72,10 +73,12 @@ export const goToEvent = async (event: TrustedEvent) => {
return await scrollToEvent(event.id)
}
const [url] = tracker.getRelays(event.id)
const urls = Array.from(tracker.getRelays(event.id))
const room = getTagValue(ROOM, event.tags)
if (url) {
if (urls.length > 0) {
const url = urls[0]
if (event.kind === THREAD) {
return goto(makeThreadPath(url, event.id))
}
@@ -105,4 +108,6 @@ export const goToEvent = async (event: TrustedEvent) => {
}
}
}
window.open(entityLink(nip19.neventEncode({id: event.id, relays: urls})))
}
+2 -2
View File
@@ -2,7 +2,7 @@
import type {Snippet} from "svelte"
import {onMount} from "svelte"
import {page} from "$app/stores"
import {ago, WEEK} from "@welshman/lib"
import {ago, MONTH} from "@welshman/lib"
import {GROUP_META, EVENT_TIME, THREAD, COMMENT, MESSAGE} from "@welshman/util"
import Page from "@lib/components/Page.svelte"
import SecondaryNav from "@lib/components/SecondaryNav.svelte"
@@ -53,7 +53,7 @@
checkConnection()
const relays = [url]
const since = ago(WEEK)
const since = ago(MONTH)
const controller = new AbortController()
// Load group meta, threads, calendar events, comments, and recent messages