2024-10-17 18:56:13 +00:00
|
|
|
<script lang="ts">
|
2026-06-04 21:10:00 +00:00
|
|
|
import {stopPropagation} from "svelte/legacy"
|
2024-10-17 23:03:50 +00:00
|
|
|
import {PublishStatus} from "@welshman/net"
|
|
|
|
|
import {displayRelayUrl} from "@welshman/util"
|
2026-09-28 18:45:09 +00:00
|
|
|
import type {Publishable} from "@welshman/app"
|
2026-06-04 21:10:00 +00:00
|
|
|
import CheckCircle from "@assets/icons/check-circle.svg?dataurl"
|
|
|
|
|
import Danger from "@assets/icons/danger-triangle.svg?dataurl"
|
|
|
|
|
import Icon from "@lib/components/Icon.svelte"
|
2024-10-17 23:03:50 +00:00
|
|
|
import Button from "@lib/components/Button.svelte"
|
2024-10-17 18:56:13 +00:00
|
|
|
|
2026-09-26 08:12:13 +00:00
|
|
|
type Props = {
|
2026-09-28 18:45:09 +00:00
|
|
|
publication: Publishable
|
2026-06-04 21:10:00 +00:00
|
|
|
retry: (url: string) => void
|
2025-02-04 00:37:14 +00:00
|
|
|
}
|
|
|
|
|
|
2026-09-28 18:45:09 +00:00
|
|
|
const {publication, retry}: Props = $props()
|
2024-10-17 18:56:13 +00:00
|
|
|
|
2026-09-28 18:45:09 +00:00
|
|
|
const successUrls = $derived($publication.getUrlsWithStatus(PublishStatus.Success))
|
|
|
|
|
const failedUrls = $derived($publication.getFailedUrls())
|
2026-06-04 21:10:00 +00:00
|
|
|
const total = $derived(successUrls.length + failedUrls.length)
|
|
|
|
|
const isPartial = $derived(successUrls.length > 0 && failedUrls.length > 0)
|
|
|
|
|
|
|
|
|
|
const title = $derived(
|
|
|
|
|
isPartial ? `Partial delivery ${successUrls.length}/${total} relays` : "Failed to send!",
|
|
|
|
|
)
|
|
|
|
|
|
2026-09-26 08:12:13 +00:00
|
|
|
const retryUrl = (url: string) => () => retry(url)
|
|
|
|
|
|
2026-06-04 21:10:00 +00:00
|
|
|
const relayMessage = (status: PublishStatus | undefined, detail: string | undefined) => {
|
|
|
|
|
if (status === PublishStatus.Timeout) {
|
2026-09-26 07:50:26 +00:00
|
|
|
return "request timed out."
|
2024-10-17 19:29:28 +00:00
|
|
|
}
|
2026-06-04 21:10:00 +00:00
|
|
|
|
2026-08-21 15:31:53 +00:00
|
|
|
if (detail) {
|
2026-09-26 07:50:26 +00:00
|
|
|
return `${detail}.`.replace(/\.+$/, ".")
|
2026-08-21 15:31:53 +00:00
|
|
|
}
|
|
|
|
|
|
2026-09-26 07:50:26 +00:00
|
|
|
return "no details received."
|
2026-06-04 21:10:00 +00:00
|
|
|
}
|
2024-10-17 18:56:13 +00:00
|
|
|
</script>
|
|
|
|
|
|
2026-06-24 20:56:53 +00:00
|
|
|
<div class="card flex min-w-72 max-w-sm flex-col gap-3 px-4 py-3">
|
2026-06-04 21:10:00 +00:00
|
|
|
<span class="flex items-center gap-2 text-sm font-medium">
|
|
|
|
|
<Icon icon={Danger} class="text-error" size={4} />
|
|
|
|
|
{title}
|
|
|
|
|
</span>
|
|
|
|
|
<div class="divider my-0"></div>
|
|
|
|
|
<div class="flex flex-col gap-3">
|
|
|
|
|
{#each successUrls as url (url)}
|
|
|
|
|
<div class="flex items-start gap-2 text-sm">
|
|
|
|
|
<Icon icon={CheckCircle} class="mt-0.5 shrink-0 text-success" size={4} />
|
|
|
|
|
<span>{displayRelayUrl(url)}</span>
|
|
|
|
|
</div>
|
|
|
|
|
{/each}
|
|
|
|
|
{#each failedUrls as url (url)}
|
2026-09-28 18:45:09 +00:00
|
|
|
{@const {detail, status} = $publication.results[url] || {}}
|
2026-06-04 21:10:00 +00:00
|
|
|
<div class="grid grid-cols-[1rem_1fr_auto] items-start gap-x-3 gap-y-1 text-sm">
|
|
|
|
|
<Icon icon={Danger} class="mt-0.5 text-error" size={4} />
|
|
|
|
|
<div class="min-w-0">
|
|
|
|
|
<p class="break-all">{displayRelayUrl(url)}</p>
|
2026-09-26 07:50:26 +00:00
|
|
|
<p class="text-xs opacity-60">{relayMessage(status, detail)}</p>
|
2026-06-04 21:10:00 +00:00
|
|
|
</div>
|
2026-09-26 08:12:13 +00:00
|
|
|
<Button class="button button-link shrink-0 px-1" onclick={stopPropagation(retryUrl(url))}>
|
2026-06-04 21:10:00 +00:00
|
|
|
Retry
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
{/each}
|
|
|
|
|
</div>
|
2024-10-17 18:56:13 +00:00
|
|
|
</div>
|