('.markdown');
if (!chatContent) {
return '';
}
const chatContentClone = chatContent.cloneNode(true) as HTMLDivElement;
const codeHeader = chatContentClone.querySelectorAll('.code-header');
codeHeader.forEach((childElement: any) => {
childElement.remove();
});
return `
${avatar}
${chatContentClone.outerHTML}
`;
});
const html = htmlTemplate.replace('{{CHAT_CONTENT}}', dom.join('\n'));
return html;
};
const map: Record void> = {
md: () => {
fileDownload({
text: shareChatData.history.map((item) => item.value).join('\n\n'),
type: 'text/markdown',
filename: 'chat.md'
});
},
html: () => {
const html = getHistoryHtml();
html &&
fileDownload({
text: html,
type: 'text/html',
filename: '聊天记录.html'
});
},
pdf: () => {
const html = getHistoryHtml();
html &&
// @ts-ignore
html2pdf(html, {
margin: 0,
filename: `聊天记录.pdf`
});
}
};
map[type]();
},
[shareChatData.history]
);
// onclick chat message context
const onclickContextMenu = useCallback(
(e: MouseEvent, message: ChatSiteItemType) => {
e.preventDefault(); // 阻止默认右键菜单
// select all text
const range = document.createRange();
range.selectNodeContents(e.currentTarget as HTMLDivElement);
window.getSelection()?.removeAllRanges();
window.getSelection()?.addRange(range);
navigator.vibrate?.(50); // 震动 50 毫秒
if (!isPc) {
PhoneContextShow.current = true;
}
setMessageContextMenuData({
left: e.clientX - 20,
top: e.clientY,
message
});
return false;
},
[isPc]
);
// 获取对话信息
const loadChatInfo = useCallback(async () => {
setIsLoading(true);
try {
const res = await initShareChatInfo({
shareId,
password
});
const history = shareChatHistory.find((item) => item._id === historyId)?.chats || [];
setShareChatData({
...res,
history
});
onClosePassword();
history.length > 0 &&
setTimeout(() => {
scrollToBottom();
}, 500);
} catch (e: any) {
toast({
status: 'error',
title: typeof e === 'string' ? e : e?.message || '初始化异常'
});
if (e?.code === 501) {
onOpenPassword();
} else {
delShareChatHistory(shareId);
router.replace(`/chat/share`);
}
}
setIsLoading(false);
return null;
}, [
setIsLoading,
shareId,
password,
setShareChatData,
shareChatHistory,
onClosePassword,
historyId,
scrollToBottom,
toast,
onOpenPassword,
delShareChatHistory,
router
]);
// 初始化聊天框
useQuery(['init', historyId], () => {
if (!shareId) {
return null;
}
if (!historyId) {
router.replace(`/chat/share?shareId=${shareId}&historyId=${new Types.ObjectId()}`);
return null;
}
return loadChatInfo();
});
// abort stream
useEffect(() => {
return () => {
window.speechSynthesis?.cancel();
isLeavePage.current = true;
controller.current?.abort();
};
}, [shareId, historyId]);
// context menu component
const RenderContextMenu = useCallback(
({ history, index }: { history: ChatSiteItemType; index: number }) => (
{hasVoiceApi && (
)}
),
[delShareChatHistoryItemById, historyId, onclickCopy, theme.borders.base]
);
return (
{/* pc always show history. */}
{isPc && (
)}
{/* 聊天内容 */}
{/* chat header */}
{!isPc && (
)}
{shareChatData.model.name}
{shareChatData.history.length > 0 ? ` (${shareChatData.history.length})` : ''}
{shareChatData.history.length > 0 ? (
) : (
)}
{/* chat content box */}
{shareChatData.history.map((item, index) => (
{item.obj === 'Human' && }
{/* avatar */}
{/* message */}
{item.obj === 'AI' ? (
onclickContextMenu(e, item)}
>
) : (
onclickContextMenu(e, item)}
>
{item.value}
)}
))}
{shareChatData.history.length === 0 && (
)}
{/* 发送区 */}
{/* 输入框 */}
{/* phone slider */}
{!isPc && (
)}
{/* context menu */}
{messageContextMenuData && (
)}
{/* password input */}
{
安全密码
密码:
setPassword(e.target.value)}
/>
}
);
};
Chat.getInitialProps = ({ query, req }: any) => {
return {
shareId: query?.shareId || '',
historyId: query?.historyId || ''
};
};
export default Chat;