- Created a .cursorignore file to manage local environment files. - Updated .env.example to reflect changes in the public app URL. - Modified the gmail workspace configuration to include the drive-suite path. - Enhanced email view components to support attachment handling and fallback for plain text bodies. - Improved user experience by updating attachment display logic and integrating inline attachment support.
55 lines
1.6 KiB
TypeScript
55 lines
1.6 KiB
TypeScript
"use client"
|
|
|
|
import { useEffect, useState } from "react"
|
|
import { apiClient } from "@/lib/api/client"
|
|
import { registerCidUrlAliases } from "@/lib/mail-cid"
|
|
|
|
/** 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 [urls, setUrls] = useState<Record<string, string>>({})
|
|
|
|
useEffect(() => {
|
|
if (!cidMap || Object.keys(cidMap).length === 0) {
|
|
setUrls({})
|
|
return
|
|
}
|
|
|
|
let cancelled = false
|
|
const objectUrls: string[] = []
|
|
void (async () => {
|
|
const next: Record<string, string> = {}
|
|
const blobByAttachmentId = new Map<string, string>()
|
|
|
|
for (const [contentId, attachmentId] of Object.entries(cidMap)) {
|
|
if (!attachmentId) continue
|
|
let blobUrl = blobByAttachmentId.get(attachmentId)
|
|
if (!blobUrl) {
|
|
try {
|
|
const blob = await apiClient.getBlob(
|
|
`/mail/attachments/${encodeURIComponent(attachmentId)}/inline`
|
|
)
|
|
blobUrl = URL.createObjectURL(blob)
|
|
blobByAttachmentId.set(attachmentId, blobUrl)
|
|
objectUrls.push(blobUrl)
|
|
} catch {
|
|
continue
|
|
}
|
|
}
|
|
registerCidUrlAliases(next, contentId, blobUrl)
|
|
}
|
|
if (!cancelled) {
|
|
setUrls(next)
|
|
} else {
|
|
for (const u of objectUrls) URL.revokeObjectURL(u)
|
|
}
|
|
})()
|
|
|
|
return () => {
|
|
cancelled = true
|
|
for (const u of objectUrls) URL.revokeObjectURL(u)
|
|
}
|
|
}, [cidMap])
|
|
|
|
return urls
|
|
}
|