68 lines
2.0 KiB
TypeScript
68 lines
2.0 KiB
TypeScript
"use client"
|
|
|
|
import { useEffect, useState } from "react"
|
|
import { useAuthStore } from "@/lib/api/auth-store"
|
|
|
|
function attachmentInlineUrl(attachmentId: string): string {
|
|
const base = process.env.NEXT_PUBLIC_API_URL ?? "/api/v1"
|
|
const normalizedBase = base.endsWith("/") ? base.slice(0, -1) : base
|
|
return `${normalizedBase}/mail/attachments/${encodeURIComponent(attachmentId)}/inline`
|
|
}
|
|
|
|
function normalizeCidKey(raw: string): string {
|
|
const trimmed = raw.trim()
|
|
if (trimmed.toLowerCase().startsWith("cid:")) {
|
|
return trimmed.slice(4).trim()
|
|
}
|
|
return trimmed
|
|
}
|
|
|
|
/** Fetches inline attachment blobs and exposes blob: URLs keyed by cid (with or without cid: prefix). */
|
|
export function useInlineCidUrls(cidMap: Record<string, string> | undefined) {
|
|
const accessToken = useAuthStore((s) => s.accessToken)
|
|
const [urls, setUrls] = useState<Record<string, string>>({})
|
|
|
|
useEffect(() => {
|
|
if (!accessToken || !cidMap || Object.keys(cidMap).length === 0) {
|
|
setUrls({})
|
|
return
|
|
}
|
|
|
|
let cancelled = false
|
|
const objectUrls: string[] = []
|
|
|
|
void (async () => {
|
|
const next: Record<string, string> = {}
|
|
for (const [contentId, attachmentId] of Object.entries(cidMap)) {
|
|
if (!attachmentId) continue
|
|
try {
|
|
const res = await fetch(attachmentInlineUrl(attachmentId), {
|
|
headers: { Authorization: `Bearer ${accessToken}` },
|
|
})
|
|
if (!res.ok) continue
|
|
const blob = await res.blob()
|
|
const blobUrl = URL.createObjectURL(blob)
|
|
objectUrls.push(blobUrl)
|
|
const key = normalizeCidKey(contentId)
|
|
next[key] = blobUrl
|
|
next[`cid:${key}`] = blobUrl
|
|
} catch {
|
|
// skip broken inline parts
|
|
}
|
|
}
|
|
if (!cancelled) {
|
|
setUrls(next)
|
|
} else {
|
|
for (const u of objectUrls) URL.revokeObjectURL(u)
|
|
}
|
|
})()
|
|
|
|
return () => {
|
|
cancelled = true
|
|
for (const u of objectUrls) URL.revokeObjectURL(u)
|
|
}
|
|
}, [accessToken, cidMap])
|
|
|
|
return urls
|
|
}
|