fixup email content rende error
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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`
|
||||
: ""}{" "}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
Generated
+10
-20
@@ -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
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user