fixup email content rende error

This commit is contained in:
oiov
2025-05-16 17:18:24 +08:00
parent 3c8097b1b9
commit deee7786a0
7 changed files with 103 additions and 41 deletions
+8 -12
View File
@@ -1,6 +1,6 @@
"use client";
import { useEffect, useState } from "react";
import { useState } from "react";
import { ForwardEmail } from "@prisma/client";
import {
File,
@@ -13,13 +13,7 @@ import {
} from "lucide-react";
import { siteConfig } from "@/config/site";
import {
cn,
downloadFile,
downloadFileFromUrl,
formatDate,
formatFileSize,
} from "@/lib/utils";
import { cn, downloadFile, formatDate, formatFileSize } from "@/lib/utils";
import { Icons } from "@/components/shared/icons";
import { BlurImg } from "../shared/blur-image";
@@ -31,6 +25,7 @@ import {
TooltipProvider,
TooltipTrigger,
} from "../ui/tooltip";
import EmailViewer from "./EmailViewer";
interface EmailDetailProps {
email: ForwardEmail | undefined;
@@ -218,16 +213,17 @@ export default function EmailDetail({
</Button>
</div>
<div className="scrollbar-hidden flex h-full flex-col justify-between overflow-y-auto px-2 py-3">
<div
<div className="scrollbar-hidden flex h-full flex-col justify-between overflow-y-auto">
{/* <div
className=""
dangerouslySetInnerHTML={{
__html: processContent(email.html || email.text || ""),
}}
/>
/> */}
<EmailViewer email={processContent(email.html || email.text || "")} />
{attachments.length > 0 && (
<div className="mt-auto border-t border-dashed py-3">
<div className="mt-auto border-t border-dashed px-2 py-3">
<h3 className="mb-2 text-sm font-semibold text-neutral-700 dark:text-neutral-400">
Attachments ({attachments.length})
</h3>
+1 -1
View File
@@ -220,7 +220,7 @@ export default function EmailList({
</Button>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<DropdownMenuItem asChild disabled>
<Button variant="ghost" size="sm" className="w-full">
<span className="text-xs">Delete selected</span>
</Button>
+2 -2
View File
@@ -522,13 +522,13 @@ export default function EmailSidebar({
</div>
{!isCollapsed && (
<div className="mt-2 flex items-center justify-between gap-2 text-xs text-gray-500">
<div className="flex items-center gap-1">
<div className="flex items-center gap-1 text-nowrap">
{email.unreadCount > 0 && (
<Badge variant="default">{email.unreadCount}</Badge>
)}
{email.count} recived
</div>
<span>
<span className="line-clamp-1 hover:line-clamp-none">
{isAdminModel
? `Created by ${email.user || email.email.slice(0, 5)} at`
: ""}{" "}
+70
View File
@@ -0,0 +1,70 @@
import { useCallback, useEffect, useRef } from "react";
const EmailViewer = ({ email }: { email: string }) => {
const iframeRef = useRef<HTMLIFrameElement>(null);
const updateIframe = useCallback(() => {
const iframe = iframeRef.current;
if (!iframe) return () => {};
const doc = iframe.contentDocument || iframe.contentWindow?.document;
if (!doc) {
console.warn("Cannot access iframe document");
return () => {};
}
doc.open();
doc.write(`
<!DOCTYPE html>
<html>
<head>
<style>
* {
box-sizing: border-box;
}
</style>
</head>
<body>${email}</body>
</html>
`);
doc.close();
const adjustHeight = () => {
if (iframe.contentDocument?.body) {
const height = iframe.contentDocument.body.scrollHeight;
iframe.style.height = `${height + 20}px`; // Add padding
}
};
iframe.addEventListener("load", adjustHeight);
// Handle dynamic content (e.g., images)
const observer = new MutationObserver(adjustHeight);
observer.observe(doc.body, { childList: true, subtree: true });
return () => {
iframe.removeEventListener("load", adjustHeight);
observer.disconnect();
};
}, [email]);
useEffect(() => {
const cleanup = updateIframe();
return cleanup;
}, [updateIframe]);
return (
<iframe
ref={iframeRef}
title="Email Content"
sandbox="allow-same-origin allow-popups"
style={{
width: "100%",
border: "none",
display: "block",
minHeight: "100px",
}}
/>
);
};
export default EmailViewer;
+11 -5
View File
@@ -462,7 +462,9 @@ export async function markEmailAsRead(emailId: string, userId: string) {
});
if (!email) {
throw new Error("邮件已读不存在或您没有权限访问此邮件");
throw new Error(
"There are no valid emails to mark as read or you do not have permission",
);
}
// 更新邮件的 readAt 字段为当前时间
@@ -504,7 +506,9 @@ export async function markEmailsAsRead(emailIds: string[], userId: string) {
const validEmailIds = emails.map((email) => email.id);
if (validEmailIds.length === 0) {
throw new Error("没有找到可标记的邮件或您没有权限");
throw new Error(
"There are no valid emails to mark as read or you do not have permission",
);
}
// 批量更新邮件的 readAt 字段
@@ -519,7 +523,7 @@ export async function markEmailsAsRead(emailIds: string[], userId: string) {
return {
updatedCount: updateResult.count,
message: `成功将 ${updateResult.count} 封邮件标记为已读`,
message: `Successfully marked ${updateResult.count} emails as read`,
};
} catch (error) {
console.error("批量标记邮件为已读失败:", error);
@@ -544,7 +548,9 @@ export async function markAllEmailsAsRead(userEmailId: string, userId: string) {
});
if (!userEmail) {
throw new Error("邮箱不存在或您没有权限");
throw new Error(
"There are no valid emails or you do not have permission",
);
}
// 更新该邮箱下所有未读邮件
@@ -560,7 +566,7 @@ export async function markAllEmailsAsRead(userEmailId: string, userId: string) {
return {
updatedCount: updateResult.count,
message: `成功将 ${updateResult.count} 封邮件标记为已读`,
message: `Successfully marked ${updateResult.count} emails as read`,
};
} catch (error) {
console.error("标记所有邮件为已读失败:", error);
+10 -20
View File
@@ -12328,8 +12328,8 @@ snapshots:
'@typescript-eslint/parser': 6.20.0(eslint@8.57.0)(typescript@5.5.3)
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0)(eslint@8.57.0)
eslint-plugin-import: 2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0)
eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0)
eslint-plugin-react: 7.35.0(eslint@8.57.0)
eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0)
@@ -12360,13 +12360,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0)(eslint@8.57.0):
eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0):
dependencies:
debug: 4.3.4
enhanced-resolve: 5.15.0
eslint: 8.57.0
eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
eslint-plugin-import: 2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)
eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
fast-glob: 3.3.2
get-tsconfig: 4.7.2
is-core-module: 2.13.1
@@ -12377,28 +12377,18 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
eslint-module-utils@2.8.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
eslint-module-utils@2.8.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 6.20.0(eslint@8.57.0)(typescript@5.5.3)
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0)(eslint@8.57.0)
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0)
transitivePeerDependencies:
- supports-color
eslint-module-utils@2.8.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 7.16.1(eslint@8.57.0)(typescript@5.5.3)
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
transitivePeerDependencies:
- supports-color
eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0):
eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0):
dependencies:
array-includes: 3.1.8
array.prototype.findlastindex: 1.2.3
@@ -12408,7 +12398,7 @@ snapshots:
doctrine: 2.1.0
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0)
eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
hasown: 2.0.2
is-core-module: 2.13.1
is-glob: 4.0.3
@@ -12419,7 +12409,7 @@ snapshots:
semver: 6.3.1
tsconfig-paths: 3.14.2
optionalDependencies:
'@typescript-eslint/parser': 7.16.1(eslint@8.57.0)(typescript@5.5.3)
'@typescript-eslint/parser': 6.20.0(eslint@8.57.0)(typescript@5.5.3)
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
+1 -1
View File
File diff suppressed because one or more lines are too long