mirror of
https://github.com/Yidadaa/ChatGPT-Next-Web.git
synced 2025-08-08 19:26:54 +08:00
Merge pull request #1678 from Yidadaa/export
feat: close #580 export messages as image
This commit is contained in:
@@ -7,7 +7,6 @@ import RenameIcon from "../icons/rename.svg";
|
||||
import ExportIcon from "../icons/share.svg";
|
||||
import ReturnIcon from "../icons/return.svg";
|
||||
import CopyIcon from "../icons/copy.svg";
|
||||
import DownloadIcon from "../icons/download.svg";
|
||||
import LoadingIcon from "../icons/three-dots.svg";
|
||||
import PromptIcon from "../icons/prompt.svg";
|
||||
import MaskIcon from "../icons/mask.svg";
|
||||
@@ -53,7 +52,7 @@ import { IconButton } from "./button";
|
||||
import styles from "./home.module.scss";
|
||||
import chatStyle from "./chat.module.scss";
|
||||
|
||||
import { ListItem, Modal, showModal, showToast } from "./ui-lib";
|
||||
import { ListItem, Modal } from "./ui-lib";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { LAST_INPUT_KEY, Path, REQUEST_TIMEOUT_MS } from "../constant";
|
||||
import { Avatar } from "./emoji";
|
||||
@@ -61,49 +60,12 @@ import { MaskAvatar, MaskConfig } from "./mask";
|
||||
import { useMaskStore } from "../store/mask";
|
||||
import { useCommand } from "../command";
|
||||
import { prettyObject } from "../utils/format";
|
||||
import { ExportMessageModal } from "./exporter";
|
||||
|
||||
const Markdown = dynamic(async () => (await import("./markdown")).Markdown, {
|
||||
loading: () => <LoadingIcon />,
|
||||
});
|
||||
|
||||
function exportMessages(messages: ChatMessage[], topic: string) {
|
||||
const mdText =
|
||||
`# ${topic}\n\n` +
|
||||
messages
|
||||
.map((m) => {
|
||||
return m.role === "user"
|
||||
? `## ${Locale.Export.MessageFromYou}:\n${m.content}`
|
||||
: `## ${Locale.Export.MessageFromChatGPT}:\n${m.content.trim()}`;
|
||||
})
|
||||
.join("\n\n");
|
||||
const filename = `${topic}.md`;
|
||||
|
||||
showModal({
|
||||
title: Locale.Export.Title,
|
||||
children: (
|
||||
<div className="markdown-body">
|
||||
<pre className={styles["export-content"]}>{mdText}</pre>
|
||||
</div>
|
||||
),
|
||||
actions: [
|
||||
<IconButton
|
||||
key="copy"
|
||||
icon={<CopyIcon />}
|
||||
bordered
|
||||
text={Locale.Export.Copy}
|
||||
onClick={() => copyToClipboard(mdText)}
|
||||
/>,
|
||||
<IconButton
|
||||
key="download"
|
||||
icon={<DownloadIcon />}
|
||||
bordered
|
||||
text={Locale.Export.Download}
|
||||
onClick={() => downloadAs(mdText, filename)}
|
||||
/>,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export function SessionConfigModel(props: { onClose: () => void }) {
|
||||
const chatStore = useChatStore();
|
||||
const session = chatStore.currentSession();
|
||||
@@ -451,6 +413,8 @@ export function Chat() {
|
||||
const config = useAppConfig();
|
||||
const fontSize = config.fontSize;
|
||||
|
||||
const [showExport, setShowExport] = useState(false);
|
||||
|
||||
const inputRef = useRef<HTMLTextAreaElement>(null);
|
||||
const [userInput, setUserInput] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
@@ -739,10 +703,7 @@ export function Chat() {
|
||||
bordered
|
||||
title={Locale.Chat.Actions.Export}
|
||||
onClick={() => {
|
||||
exportMessages(
|
||||
session.messages.filter((msg) => !msg.isError),
|
||||
session.topic,
|
||||
);
|
||||
setShowExport(true);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@@ -917,6 +878,10 @@ export function Chat() {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{showExport && (
|
||||
<ExportMessageModal onClose={() => setShowExport(false)} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user