Render rich issue attachment previews
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import type { IssueAttachment } from "@paperclipai/shared";
|
||||
import { isVideoContentType } from "./issue-output";
|
||||
|
||||
function normalizedContentType(attachment: Pick<IssueAttachment, "contentType">) {
|
||||
return attachment.contentType.toLowerCase().split(";")[0]?.trim() ?? "";
|
||||
}
|
||||
|
||||
export function attachmentFilename(attachment: Pick<IssueAttachment, "id" | "originalFilename">) {
|
||||
return attachment.originalFilename ?? attachment.id;
|
||||
}
|
||||
|
||||
export function attachmentOpenPath(
|
||||
attachment: Pick<IssueAttachment, "contentPath" | "openPath">,
|
||||
) {
|
||||
return attachment.openPath ?? attachment.contentPath;
|
||||
}
|
||||
|
||||
export function attachmentDownloadPath(
|
||||
attachment: Pick<IssueAttachment, "contentPath" | "downloadPath">,
|
||||
) {
|
||||
return attachment.downloadPath ?? `${attachment.contentPath}?download=1`;
|
||||
}
|
||||
|
||||
export function isImageAttachment(attachment: Pick<IssueAttachment, "contentType">) {
|
||||
return normalizedContentType(attachment).startsWith("image/");
|
||||
}
|
||||
|
||||
export function isVideoAttachment(attachment: Pick<IssueAttachment, "contentType">) {
|
||||
return isVideoContentType(normalizedContentType(attachment));
|
||||
}
|
||||
|
||||
export function isMarkdownAttachment(
|
||||
attachment: Pick<IssueAttachment, "contentType" | "originalFilename">,
|
||||
) {
|
||||
const contentType = normalizedContentType(attachment);
|
||||
if (
|
||||
contentType === "text/markdown" ||
|
||||
contentType === "text/x-markdown" ||
|
||||
contentType === "application/markdown" ||
|
||||
contentType === "application/x-markdown"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const filename = (attachment.originalFilename ?? "").toLowerCase();
|
||||
return filename.endsWith(".md") || filename.endsWith(".markdown");
|
||||
}
|
||||
@@ -67,6 +67,7 @@ export const queryKeys = {
|
||||
? (["issues", "cost-summary", issueId, "exclude-root"] as const)
|
||||
: (["issues", "cost-summary", issueId] as const),
|
||||
attachments: (issueId: string) => ["issues", "attachments", issueId] as const,
|
||||
attachmentPreview: (attachmentId: string) => ["issues", "attachment-preview", attachmentId] as const,
|
||||
documents: (issueId: string) => ["issues", "documents", issueId] as const,
|
||||
document: (issueId: string, key: string) => ["issues", "document", issueId, key] as const,
|
||||
documentRevisions: (issueId: string, key: string) => ["issues", "document-revisions", issueId, key] as const,
|
||||
|
||||
Reference in New Issue
Block a user