feat: 集中实现全局Toast通知功能
This commit is contained in:
1 parent
3192f046ed
commit
68e7d17924
4 files changed
+90
-232
No files matched your search
@@ -21,35 +21,16 @@ interface Attachment {
|
||||
|
||||
const EmailDetail: React.FC<EmailDetailProps> = ({ emailId, onClose }) => {
|
||||
const { t } = useTranslation();
|
||||
const { emailCache, addToEmailCache, handleMailboxNotFound } = useContext(MailboxContext);
|
||||
// fix: 从 context 中获取全局通知函数
|
||||
const { emailCache, addToEmailCache, handleMailboxNotFound, showErrorMessage, showSuccessMessage } = useContext(MailboxContext);
|
||||
const [email, setEmail] = useState<Email | null>(null);
|
||||
const [attachments, setAttachments] = useState<Attachment[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [isLoadingAttachments, setIsLoadingAttachments] = useState(false);
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
const [successMessage, setSuccessMessage] = useState<string | null>(null);
|
||||
const errorTimeoutRef = useRef<number | null>(null);
|
||||
const successTimeoutRef = useRef<number | null>(null);
|
||||
|
||||
// 清除提示的定时器
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (errorTimeoutRef.current) {
|
||||
window.clearTimeout(errorTimeoutRef.current);
|
||||
}
|
||||
if (successTimeoutRef.current) {
|
||||
window.clearTimeout(successTimeoutRef.current);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchEmail = async () => {
|
||||
try {
|
||||
// 清除之前的错误和成功信息
|
||||
setErrorMessage(null);
|
||||
setSuccessMessage(null);
|
||||
|
||||
// 首先检查缓存中是否有该邮件
|
||||
if (emailCache[emailId]) {
|
||||
setEmail(emailCache[emailId].email);
|
||||
@@ -86,22 +67,15 @@ const EmailDetail: React.FC<EmailDetailProps> = ({ emailId, onClose }) => {
|
||||
throw new Error(data.error || 'Unknown error');
|
||||
}
|
||||
} catch (error) {
|
||||
setErrorMessage(t('email.fetchFailed'));
|
||||
|
||||
// 3秒后清除错误信息
|
||||
if (errorTimeoutRef.current) {
|
||||
window.clearTimeout(errorTimeoutRef.current);
|
||||
}
|
||||
errorTimeoutRef.current = window.setTimeout(() => {
|
||||
setErrorMessage(null);
|
||||
}, 3000);
|
||||
// fix: 使用全局通知函数
|
||||
showErrorMessage(t('email.fetchFailed'));
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchEmail();
|
||||
}, [emailId, t, emailCache, addToEmailCache, handleMailboxNotFound, onClose]);
|
||||
}, [emailId, t, emailCache, addToEmailCache, handleMailboxNotFound, onClose, showErrorMessage]);
|
||||
|
||||
const fetchAttachments = async (emailId: string, emailData?: Email) => {
|
||||
try {
|
||||
@@ -138,10 +112,6 @@ const EmailDetail: React.FC<EmailDetailProps> = ({ emailId, onClose }) => {
|
||||
|
||||
const handleDelete = async () => {
|
||||
try {
|
||||
// 清除之前的错误和成功信息
|
||||
setErrorMessage(null);
|
||||
setSuccessMessage(null);
|
||||
|
||||
const response = await fetch(`${API_BASE_URL}/api/emails/${emailId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
@@ -152,28 +122,19 @@ const EmailDetail: React.FC<EmailDetailProps> = ({ emailId, onClose }) => {
|
||||
|
||||
const data = await response.json();
|
||||
if (data.success) {
|
||||
setSuccessMessage(t('email.deleteSuccess'));
|
||||
// fix: 使用全局通知函数
|
||||
showSuccessMessage(t('email.deleteSuccess'));
|
||||
|
||||
// 2秒后关闭邮件详情
|
||||
if (successTimeoutRef.current) {
|
||||
window.clearTimeout(successTimeoutRef.current);
|
||||
}
|
||||
successTimeoutRef.current = window.setTimeout(() => {
|
||||
setTimeout(() => {
|
||||
onClose();
|
||||
}, 2000);
|
||||
} else {
|
||||
throw new Error(data.error || 'Unknown error');
|
||||
}
|
||||
} catch (error) {
|
||||
setErrorMessage(t('email.deleteFailed'));
|
||||
|
||||
// 3秒后清除错误信息
|
||||
if (errorTimeoutRef.current) {
|
||||
window.clearTimeout(errorTimeoutRef.current);
|
||||
}
|
||||
errorTimeoutRef.current = window.setTimeout(() => {
|
||||
setErrorMessage(null);
|
||||
}, 3000);
|
||||
// fix: 使用全局通知函数
|
||||
showErrorMessage(t('email.deleteFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -285,13 +246,7 @@ const EmailDetail: React.FC<EmailDetailProps> = ({ emailId, onClose }) => {
|
||||
|
||||
return (
|
||||
<div className="border rounded-lg p-6">
|
||||
{/* 错误和成功提示 */}
|
||||
{(errorMessage || successMessage) && (
|
||||
<div className={`p-3 mb-4 rounded-md ${errorMessage ? 'bg-red-100 text-red-800' : 'bg-green-100 text-green-800'}`}>
|
||||
{errorMessage || successMessage}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* fix: 移除局部的错误和成功提示,使用全局通知 */}
|
||||
{isLoading ? (
|
||||
<div className="flex items-center justify-center h-64">
|
||||
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import React, { useState, useRef, useEffect, useContext } from 'react'; // feat: 导入 useContext
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { createRandomMailbox, createCustomMailbox } from '../utils/api';
|
||||
import MailboxSwitcher from './MailboxSwitcher';
|
||||
import { MailboxContext } from '../contexts/MailboxContext'; // feat: 导入 MailboxContext
|
||||
|
||||
interface HeaderMailboxProps {
|
||||
mailbox: Mailbox | null;
|
||||
@@ -19,20 +20,18 @@ const HeaderMailbox: React.FC<HeaderMailboxProps> = ({
|
||||
isLoading
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
// feat: 从 context 中获取全局通知函数
|
||||
const { showSuccessMessage, showErrorMessage } = useContext(MailboxContext);
|
||||
const [isCustomMode, setIsCustomMode] = useState(false);
|
||||
const [customAddress, setCustomAddress] = useState('');
|
||||
const [selectedDomain, setSelectedDomain] = useState(domain);
|
||||
const [isActionLoading, setIsActionLoading] = useState(false);
|
||||
const [showCopyTooltip, setShowCopyTooltip] = useState(false);
|
||||
const [copyError, setCopyError] = useState<string | null>(null);
|
||||
const [refreshError, setRefreshError] = useState<string | null>(null);
|
||||
// fix: 移除独立的错误状态,因为将使用全局通知
|
||||
const [customAddressError, setCustomAddressError] = useState<string | null>(null);
|
||||
const [customAddressSuccess, setCustomAddressSuccess] = useState<string | null>(null);
|
||||
const [showRefreshSuccess, setShowRefreshSuccess] = useState(false);
|
||||
const copyTooltipTimeoutRef = useRef<number | null>(null);
|
||||
const refreshSuccessTimeoutRef = useRef<number | null>(null);
|
||||
const successMessageTimeoutRef = useRef<number | null>(null);
|
||||
const errorMessageTimeoutRef = useRef<number | null>(null);
|
||||
|
||||
// 当props中的domain变化时更新selectedDomain
|
||||
useEffect(() => {
|
||||
@@ -48,12 +47,6 @@ const HeaderMailbox: React.FC<HeaderMailboxProps> = ({
|
||||
if (refreshSuccessTimeoutRef.current) {
|
||||
window.clearTimeout(refreshSuccessTimeoutRef.current);
|
||||
}
|
||||
if (successMessageTimeoutRef.current) {
|
||||
window.clearTimeout(successMessageTimeoutRef.current);
|
||||
}
|
||||
if (errorMessageTimeoutRef.current) {
|
||||
window.clearTimeout(errorMessageTimeoutRef.current);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
@@ -61,13 +54,10 @@ const HeaderMailbox: React.FC<HeaderMailboxProps> = ({
|
||||
|
||||
// 复制邮箱地址到剪贴板
|
||||
const copyToClipboard = () => {
|
||||
// 清除之前的错误信息
|
||||
setCopyError(null);
|
||||
|
||||
const fullAddress = mailbox.address.includes('@') ? mailbox.address : `${mailbox.address}@${selectedDomain}`;
|
||||
navigator.clipboard.writeText(fullAddress)
|
||||
.then(() => {
|
||||
// 显示复制成功提示
|
||||
// 显示复制成功提示 (Tooltip 形式,保留局部状态)
|
||||
setShowCopyTooltip(true);
|
||||
|
||||
// 2秒后隐藏提示
|
||||
@@ -79,24 +69,13 @@ const HeaderMailbox: React.FC<HeaderMailboxProps> = ({
|
||||
}, 2000);
|
||||
})
|
||||
.catch(() => {
|
||||
// 显示复制失败错误
|
||||
setCopyError(t('mailbox.copyFailed'));
|
||||
|
||||
// 3秒后隐藏错误
|
||||
if (errorMessageTimeoutRef.current) {
|
||||
window.clearTimeout(errorMessageTimeoutRef.current);
|
||||
}
|
||||
errorMessageTimeoutRef.current = window.setTimeout(() => {
|
||||
setCopyError(null);
|
||||
}, 3000);
|
||||
// fix: 使用全局通知函数显示复制失败
|
||||
showErrorMessage(t('mailbox.copyFailed'));
|
||||
});
|
||||
};
|
||||
|
||||
// 更换随机邮箱
|
||||
const handleRefreshMailbox = async () => {
|
||||
// 清除之前的错误信息
|
||||
setRefreshError(null);
|
||||
|
||||
setIsActionLoading(true);
|
||||
const result = await createRandomMailbox();
|
||||
setIsActionLoading(false);
|
||||
@@ -104,7 +83,7 @@ const HeaderMailbox: React.FC<HeaderMailboxProps> = ({
|
||||
if (result.success && result.mailbox) {
|
||||
onMailboxChange(result.mailbox);
|
||||
|
||||
// 显示更新成功提示
|
||||
// 显示更新成功提示 (Tooltip 形式,保留局部状态)
|
||||
setShowRefreshSuccess(true);
|
||||
|
||||
// 3秒后隐藏提示
|
||||
@@ -115,16 +94,8 @@ const HeaderMailbox: React.FC<HeaderMailboxProps> = ({
|
||||
setShowRefreshSuccess(false);
|
||||
}, 3000);
|
||||
} else {
|
||||
// 显示刷新失败错误
|
||||
setRefreshError(t('mailbox.refreshFailed'));
|
||||
|
||||
// 3秒后隐藏错误
|
||||
if (errorMessageTimeoutRef.current) {
|
||||
window.clearTimeout(errorMessageTimeoutRef.current);
|
||||
}
|
||||
errorMessageTimeoutRef.current = window.setTimeout(() => {
|
||||
setRefreshError(null);
|
||||
}, 3000);
|
||||
// fix: 使用全局通知函数显示刷新失败
|
||||
showErrorMessage(t('mailbox.refreshFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -132,9 +103,8 @@ const HeaderMailbox: React.FC<HeaderMailboxProps> = ({
|
||||
const handleCreateCustom = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
// 清除之前的错误和成功信息
|
||||
// 清除之前的错误信息
|
||||
setCustomAddressError(null);
|
||||
setCustomAddressSuccess(null);
|
||||
|
||||
if (!customAddress.trim()) {
|
||||
setCustomAddressError(t('mailbox.invalidAddress'));
|
||||
@@ -147,18 +117,13 @@ const HeaderMailbox: React.FC<HeaderMailboxProps> = ({
|
||||
|
||||
if (result.success && result.mailbox) {
|
||||
onMailboxChange(result.mailbox);
|
||||
|
||||
// 显示成功消息在表单下方
|
||||
setCustomAddressSuccess(t('mailbox.createSuccess'));
|
||||
// fix: 使用全局通知函数显示成功
|
||||
showSuccessMessage(t('mailbox.createSuccess'));
|
||||
|
||||
// 3秒后自动关闭表单
|
||||
if (successMessageTimeoutRef.current) {
|
||||
window.clearTimeout(successMessageTimeoutRef.current);
|
||||
}
|
||||
successMessageTimeoutRef.current = window.setTimeout(() => {
|
||||
setTimeout(() => {
|
||||
setIsCustomMode(false);
|
||||
setCustomAddress('');
|
||||
setCustomAddressSuccess(null);
|
||||
}, 3000);
|
||||
} else {
|
||||
// 检查错误信息是否包含"邮箱地址已存在"
|
||||
@@ -167,9 +132,11 @@ const HeaderMailbox: React.FC<HeaderMailboxProps> = ({
|
||||
String(result.error).includes('已存在');
|
||||
|
||||
if (isAddressExistsError) {
|
||||
// fix: 对于表单内校验错误,保留局部状态提示
|
||||
setCustomAddressError(t('mailbox.addressExists'));
|
||||
} else {
|
||||
setCustomAddressError(t('mailbox.createFailed'));
|
||||
// fix: 对于通用创建失败,使用全局通知
|
||||
showErrorMessage(t('mailbox.createFailed'));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -179,7 +146,6 @@ const HeaderMailbox: React.FC<HeaderMailboxProps> = ({
|
||||
setIsCustomMode(false);
|
||||
setCustomAddress('');
|
||||
setCustomAddressError(null);
|
||||
setCustomAddressSuccess(null);
|
||||
};
|
||||
|
||||
// 移动设备上的邮箱地址显示
|
||||
@@ -222,7 +188,6 @@ const HeaderMailbox: React.FC<HeaderMailboxProps> = ({
|
||||
onChange={(e) => {
|
||||
setCustomAddress(e.target.value);
|
||||
if (customAddressError) setCustomAddressError(null);
|
||||
if (customAddressSuccess) setCustomAddressSuccess(null);
|
||||
}}
|
||||
className={`w-32 md:w-40 px-2 py-1 text-sm border rounded-l-md focus:outline-none focus:ring-1 focus:ring-primary ${
|
||||
customAddressError ? 'border-red-500' : ''
|
||||
@@ -274,12 +239,6 @@ const HeaderMailbox: React.FC<HeaderMailboxProps> = ({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 成功信息显示 */}
|
||||
{customAddressSuccess && (
|
||||
<div className="text-green-500 text-xs px-1">
|
||||
{customAddressSuccess}
|
||||
</div>
|
||||
)}
|
||||
</form>
|
||||
) : (
|
||||
<>
|
||||
@@ -360,12 +319,6 @@ const HeaderMailbox: React.FC<HeaderMailboxProps> = ({
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 错误信息显示 */}
|
||||
{(copyError || refreshError) && (
|
||||
<div className="text-red-500 text-xs mt-1">
|
||||
{copyError || refreshError}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 移动版显示 */}
|
||||
@@ -433,13 +386,6 @@ const HeaderMailbox: React.FC<HeaderMailboxProps> = ({
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 错误信息显示 */}
|
||||
{(copyError || refreshError) && (
|
||||
<div className="text-red-500 text-xs mt-1">
|
||||
{copyError || refreshError}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -40,6 +40,9 @@ interface MailboxContextType {
|
||||
handleMailboxNotFound: () => Promise<void>;
|
||||
errorMessage: string | null;
|
||||
successMessage: string | null;
|
||||
// feat: 添加用于显示全局通知的函数
|
||||
showSuccessMessage: (message: string) => void;
|
||||
showErrorMessage: (message: string) => void;
|
||||
}
|
||||
|
||||
export const MailboxContext = createContext<MailboxContextType>({
|
||||
@@ -62,7 +65,10 @@ export const MailboxContext = createContext<MailboxContextType>({
|
||||
clearEmailCache: () => {},
|
||||
handleMailboxNotFound: async () => {},
|
||||
errorMessage: null,
|
||||
successMessage: null
|
||||
successMessage: null,
|
||||
// feat: 提供默认空函数
|
||||
showSuccessMessage: () => {},
|
||||
showErrorMessage: () => {},
|
||||
});
|
||||
|
||||
interface MailboxProviderProps {
|
||||
@@ -83,6 +89,29 @@ export const MailboxProvider: React.FC<MailboxProviderProps> = ({ children }) =>
|
||||
const errorTimeoutRef = useRef<number | null>(null);
|
||||
const successTimeoutRef = useRef<number | null>(null);
|
||||
|
||||
// feat: 创建显示成功消息的函数
|
||||
const showSuccessMessage = (message: string) => {
|
||||
setSuccessMessage(message);
|
||||
if (successTimeoutRef.current) {
|
||||
window.clearTimeout(successTimeoutRef.current);
|
||||
}
|
||||
successTimeoutRef.current = window.setTimeout(() => {
|
||||
setSuccessMessage(null);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
// feat: 创建显示错误消息的函数
|
||||
const showErrorMessage = (message: string) => {
|
||||
setErrorMessage(message);
|
||||
if (errorTimeoutRef.current) {
|
||||
window.clearTimeout(errorTimeoutRef.current);
|
||||
}
|
||||
errorTimeoutRef.current = window.setTimeout(() => {
|
||||
setErrorMessage(null);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
|
||||
// 清除提示的定时器
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
@@ -137,15 +166,8 @@ export const MailboxProvider: React.FC<MailboxProviderProps> = ({ children }) =>
|
||||
clearEmailCache();
|
||||
} else {
|
||||
console.error('createNewMailbox: Failed to create mailbox:', result.error);
|
||||
setErrorMessage(t('mailbox.createFailed'));
|
||||
|
||||
// 3秒后清除错误信息
|
||||
if (errorTimeoutRef.current) {
|
||||
window.clearTimeout(errorTimeoutRef.current);
|
||||
}
|
||||
errorTimeoutRef.current = window.setTimeout(() => {
|
||||
setErrorMessage(null);
|
||||
}, 3000);
|
||||
// fix: 使用全局通知函数
|
||||
showErrorMessage(t('mailbox.createFailed'));
|
||||
throw new Error('Failed to create mailbox');
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -169,8 +191,8 @@ export const MailboxProvider: React.FC<MailboxProviderProps> = ({ children }) =>
|
||||
const result = await apiDeleteMailbox(mailbox.address);
|
||||
|
||||
if (result.success) {
|
||||
// 显示成功信息
|
||||
setSuccessMessage(t('mailbox.deleteSuccess'));
|
||||
// fix: 使用全局通知函数
|
||||
showSuccessMessage(t('mailbox.deleteSuccess'));
|
||||
|
||||
// 清除本地数据
|
||||
setMailbox(null);
|
||||
@@ -179,41 +201,17 @@ export const MailboxProvider: React.FC<MailboxProviderProps> = ({ children }) =>
|
||||
removeMailboxFromLocalStorage();
|
||||
clearEmailCache();
|
||||
|
||||
// 3秒后清除成功信息
|
||||
if (successTimeoutRef.current) {
|
||||
window.clearTimeout(successTimeoutRef.current);
|
||||
}
|
||||
successTimeoutRef.current = window.setTimeout(() => {
|
||||
setSuccessMessage(null);
|
||||
}, 3000);
|
||||
|
||||
// 创建新邮箱
|
||||
await createNewMailbox();
|
||||
} else {
|
||||
// 显示错误信息
|
||||
setErrorMessage(t('mailbox.deleteFailed'));
|
||||
|
||||
// 3秒后清除错误信息
|
||||
if (errorTimeoutRef.current) {
|
||||
window.clearTimeout(errorTimeoutRef.current);
|
||||
}
|
||||
errorTimeoutRef.current = window.setTimeout(() => {
|
||||
setErrorMessage(null);
|
||||
}, 3000);
|
||||
// fix: 使用全局通知函数
|
||||
showErrorMessage(t('mailbox.deleteFailed'));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error deleting mailbox:', error);
|
||||
|
||||
// 显示错误信息
|
||||
setErrorMessage(t('mailbox.deleteFailed'));
|
||||
|
||||
// 3秒后清除错误信息
|
||||
if (errorTimeoutRef.current) {
|
||||
window.clearTimeout(errorTimeoutRef.current);
|
||||
}
|
||||
errorTimeoutRef.current = window.setTimeout(() => {
|
||||
setErrorMessage(null);
|
||||
}, 3000);
|
||||
// fix: 使用全局通知函数
|
||||
showErrorMessage(t('mailbox.deleteFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -265,8 +263,8 @@ export const MailboxProvider: React.FC<MailboxProviderProps> = ({ children }) =>
|
||||
|
||||
// [fix]: 重构处理邮箱不存在的逻辑,避免页面刷新
|
||||
const handleMailboxNotFound = async () => {
|
||||
// 设置提示信息,告知用户正在创建新邮箱
|
||||
setSuccessMessage(t('mailbox.creatingNew'));
|
||||
// fix: 使用全局通知函数
|
||||
showSuccessMessage(t('mailbox.creatingNew'));
|
||||
|
||||
// 清除当前无效的邮箱信息
|
||||
removeMailboxFromLocalStorage();
|
||||
@@ -274,14 +272,6 @@ export const MailboxProvider: React.FC<MailboxProviderProps> = ({ children }) =>
|
||||
|
||||
// 异步创建新邮箱,并更新应用状态
|
||||
await createNewMailbox();
|
||||
|
||||
// 3秒后清除提示信息
|
||||
if (successTimeoutRef.current) {
|
||||
window.clearTimeout(successTimeoutRef.current);
|
||||
}
|
||||
successTimeoutRef.current = window.setTimeout(() => {
|
||||
setSuccessMessage(null);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
// 添加邮件到缓存
|
||||
@@ -376,10 +366,13 @@ export const MailboxProvider: React.FC<MailboxProviderProps> = ({ children }) =>
|
||||
clearEmailCache,
|
||||
handleMailboxNotFound,
|
||||
errorMessage,
|
||||
successMessage
|
||||
successMessage,
|
||||
// feat: 将函数添加到 context value 中
|
||||
showSuccessMessage,
|
||||
showErrorMessage,
|
||||
}}
|
||||
>
|
||||
{/* [feat] 将错误和成功提示移至此处,作为全局通知组件 */}
|
||||
{/* [feat] 全局通知组件 */}
|
||||
{(errorMessage || successMessage) && (
|
||||
<div className="fixed top-4 right-4 z-50 p-3 rounded-md shadow-lg max-w-md" style={{ backgroundColor: errorMessage ? '#FEE2E2' : '#ECFDF5', color: errorMessage ? '#991B1B' : '#065F46' }}>
|
||||
{errorMessage || successMessage}
|
||||
|
||||
@@ -15,28 +15,15 @@ const MailboxPage: React.FC = () => {
|
||||
emails,
|
||||
isEmailsLoading,
|
||||
autoRefresh,
|
||||
setAutoRefresh
|
||||
setAutoRefresh,
|
||||
// feat: 从 context 中获取全局通知函数
|
||||
showSuccessMessage,
|
||||
showErrorMessage
|
||||
} = useContext(MailboxContext);
|
||||
|
||||
const [mailbox, setMailbox] = useState<Mailbox | null>(null);
|
||||
const [selectedEmail, setSelectedEmail] = useState<string | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
const [successMessage, setSuccessMessage] = useState<string | null>(null);
|
||||
const errorTimeoutRef = useRef<number | null>(null);
|
||||
const successTimeoutRef = useRef<number | null>(null);
|
||||
|
||||
// 清除提示的定时器
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (errorTimeoutRef.current) {
|
||||
window.clearTimeout(errorTimeoutRef.current);
|
||||
}
|
||||
if (successTimeoutRef.current) {
|
||||
window.clearTimeout(successTimeoutRef.current);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
// 获取邮箱信息
|
||||
useEffect(() => {
|
||||
@@ -49,13 +36,11 @@ const MailboxPage: React.FC = () => {
|
||||
|
||||
if (!response.ok) {
|
||||
if (response.status === 404) {
|
||||
setErrorMessage(t('mailbox.invalidAddress'));
|
||||
// fix: 使用全局通知函数
|
||||
showErrorMessage(t('mailbox.invalidAddress'));
|
||||
|
||||
// 3秒后导航到首页
|
||||
if (errorTimeoutRef.current) {
|
||||
window.clearTimeout(errorTimeoutRef.current);
|
||||
}
|
||||
errorTimeoutRef.current = window.setTimeout(() => {
|
||||
setTimeout(() => {
|
||||
navigate('/');
|
||||
}, 3000);
|
||||
return;
|
||||
@@ -70,22 +55,15 @@ const MailboxPage: React.FC = () => {
|
||||
throw new Error(data.error || 'Unknown error');
|
||||
}
|
||||
} catch (error) {
|
||||
setErrorMessage(String(error));
|
||||
|
||||
// 3秒后清除错误信息
|
||||
if (errorTimeoutRef.current) {
|
||||
window.clearTimeout(errorTimeoutRef.current);
|
||||
}
|
||||
errorTimeoutRef.current = window.setTimeout(() => {
|
||||
setErrorMessage(null);
|
||||
}, 3000);
|
||||
// fix: 使用全局通知函数
|
||||
showErrorMessage(String(error));
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchMailbox();
|
||||
}, [address, navigate, t]);
|
||||
}, [address, navigate, t, showErrorMessage]);
|
||||
|
||||
// 处理删除邮箱
|
||||
const handleDeleteMailbox = async () => {
|
||||
@@ -102,39 +80,25 @@ const MailboxPage: React.FC = () => {
|
||||
|
||||
const data = await response.json();
|
||||
if (data.success) {
|
||||
setSuccessMessage(t('mailbox.deleteSuccess'));
|
||||
// fix: 使用全局通知函数
|
||||
showSuccessMessage(t('mailbox.deleteSuccess'));
|
||||
|
||||
// 2秒后导航到首页
|
||||
if (successTimeoutRef.current) {
|
||||
window.clearTimeout(successTimeoutRef.current);
|
||||
}
|
||||
successTimeoutRef.current = window.setTimeout(() => {
|
||||
setTimeout(() => {
|
||||
navigate('/');
|
||||
}, 2000);
|
||||
} else {
|
||||
throw new Error(data.error || 'Unknown error');
|
||||
}
|
||||
} catch (error) {
|
||||
setErrorMessage(t('mailbox.deleteFailed'));
|
||||
|
||||
// 3秒后清除错误信息
|
||||
if (errorTimeoutRef.current) {
|
||||
window.clearTimeout(errorTimeoutRef.current);
|
||||
}
|
||||
errorTimeoutRef.current = window.setTimeout(() => {
|
||||
setErrorMessage(null);
|
||||
}, 3000);
|
||||
// fix: 使用全局通知函数
|
||||
showErrorMessage(t('mailbox.deleteFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col space-y-6">
|
||||
{/* 错误和成功提示 */}
|
||||
{(errorMessage || successMessage) && (
|
||||
<div className={`p-3 rounded-md ${errorMessage ? 'bg-red-100 text-red-800' : 'bg-green-100 text-green-800'}`}>
|
||||
{errorMessage || successMessage}
|
||||
</div>
|
||||
)}
|
||||
{/* fix: 移除局部的错误和成功提示 */}
|
||||
|
||||
{mailbox && (
|
||||
<MailboxInfo
|
||||
|
||||
Reference in new issue
Block a user