feat: remove ai export
This commit is contained in:
parent
5f2b93694e
commit
f100d09efd
|
|
@ -1,7 +1,5 @@
|
|||
import type { ReactNode } from "react"
|
||||
import { useCallback, useRef } from "react"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { toast } from "sonner"
|
||||
|
||||
import {
|
||||
AIChatPanelStyle,
|
||||
|
|
@ -16,8 +14,6 @@ import {
|
|||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "~/components/ui/dropdown-menu/dropdown-menu"
|
||||
import { useChatActions, useCurrentTitle } from "~/modules/ai-chat/store/hooks"
|
||||
import { downloadMarkdown, exportChatToMarkdown } from "~/modules/ai-chat/utils/export"
|
||||
import { useSettingModal } from "~/modules/settings/modal/use-setting-modal-hack"
|
||||
|
||||
export const ChatMoreDropdown = ({
|
||||
|
|
@ -29,31 +25,9 @@ export const ChatMoreDropdown = ({
|
|||
asChild?: boolean
|
||||
canToggleMode?: boolean
|
||||
}) => {
|
||||
const currentTitle = useCurrentTitle()
|
||||
const panelStyle = useAIChatPanelStyle()
|
||||
const settingModalPresent = useSettingModal()
|
||||
|
||||
const chatActions = useChatActions()
|
||||
const { t } = useTranslation("ai")
|
||||
|
||||
const handleExport = useCallback(() => {
|
||||
const messages = chatActions.getMessages()
|
||||
if (messages.length === 0) {
|
||||
toast.error(t("export_empty_chat"))
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const markdown = exportChatToMarkdown(messages, currentTitle)
|
||||
const filename = `${currentTitle || "AI_Chat"}_${new Date().toISOString().slice(0, 10)}.md`
|
||||
downloadMarkdown(markdown, filename)
|
||||
toast.success(t("export_success"))
|
||||
} catch (error) {
|
||||
toast.error(t("export_error"))
|
||||
console.error("Export error:", error)
|
||||
}
|
||||
}, [chatActions, currentTitle, t])
|
||||
|
||||
const handleToggleMode = useCallback(() => {
|
||||
const newStyle =
|
||||
panelStyle === AIChatPanelStyle.Fixed ? AIChatPanelStyle.Floating : AIChatPanelStyle.Fixed
|
||||
|
|
@ -68,12 +42,6 @@ export const ChatMoreDropdown = ({
|
|||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild={asChild}>{triggerElement}</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="w-56">
|
||||
<DropdownMenuItem onClick={handleExport}>
|
||||
<i className="i-mgc-download-2-cute-re mr-2 size-4" />
|
||||
<span>Export Chat</span>
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuSeparator />
|
||||
{canToggleMode && (
|
||||
<>
|
||||
<DropdownMenuItem onClick={handleToggleMode}>
|
||||
|
|
|
|||
|
|
@ -1,77 +0,0 @@
|
|||
import type { BizUIMessage } from "../store/types"
|
||||
|
||||
export const exportChatToMarkdown = (messages: BizUIMessage[], title?: string) => {
|
||||
const date = new Date().toLocaleString()
|
||||
let markdown = `# ${title || "AI Chat Export"}\n\n`
|
||||
markdown += `*Exported on ${date}*\n\n---\n\n`
|
||||
|
||||
messages.forEach((message) => {
|
||||
const timestamp = message.metadata?.finishTime
|
||||
? new Date(message.metadata.finishTime).toLocaleString()
|
||||
: ""
|
||||
|
||||
if (message.role === "user") {
|
||||
markdown += `## 👤 User\n`
|
||||
if (timestamp) markdown += `*${timestamp}*\n\n`
|
||||
|
||||
// Extract text content from parts in single pass
|
||||
const textContent =
|
||||
message.parts
|
||||
?.reduce((acc, part) => {
|
||||
if (part.type === "text") {
|
||||
acc.push(part.text)
|
||||
} else if (part.type === "data-rich-text") {
|
||||
acc.push(part.data.text)
|
||||
}
|
||||
return acc
|
||||
}, [] as string[])
|
||||
.join("\n") || ""
|
||||
|
||||
markdown += `${textContent}\n\n`
|
||||
} else if (message.role === "assistant") {
|
||||
markdown += `## 🤖 ${APP_NAME} AI\n`
|
||||
if (timestamp) markdown += `*${timestamp}*\n\n`
|
||||
|
||||
// Extract text content from parts in single pass
|
||||
const textContent =
|
||||
message.parts
|
||||
?.reduce((acc, part) => {
|
||||
if (part.type === "text") {
|
||||
acc.push(part.text)
|
||||
} else if (part.type === "data-rich-text") {
|
||||
acc.push(part.data.text)
|
||||
}
|
||||
return acc
|
||||
}, [] as string[])
|
||||
.join("\n") || ""
|
||||
|
||||
markdown += `${textContent}\n\n`
|
||||
|
||||
// Add tool invocations if any
|
||||
const toolParts = message.parts?.filter((part) => part.type.startsWith("tool-"))
|
||||
if (toolParts && toolParts.length > 0) {
|
||||
markdown += `\n### 🔧 Tools Used:\n`
|
||||
toolParts.forEach((tool) => {
|
||||
markdown += `- **${tool.type}**\n`
|
||||
})
|
||||
markdown += "\n"
|
||||
}
|
||||
}
|
||||
|
||||
markdown += "---\n\n"
|
||||
})
|
||||
|
||||
return markdown
|
||||
}
|
||||
|
||||
export const downloadMarkdown = (content: string, filename: string) => {
|
||||
const blob = new Blob([content], { type: "text/markdown;charset=utf-8" })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const link = document.createElement("a")
|
||||
link.href = url
|
||||
link.download = filename
|
||||
document.body.append(link)
|
||||
link.click()
|
||||
link.remove()
|
||||
URL.revokeObjectURL(url)
|
||||
}
|
||||
|
|
@ -32,9 +32,6 @@
|
|||
"delete_chat_error": "Failed to delete chat",
|
||||
"delete_chat_message": "Are you sure you want to delete \"{{title}}\"? This action cannot be undone.",
|
||||
"delete_chat_success": "Chat deleted successfully",
|
||||
"export_empty_chat": "Cannot export an empty chat",
|
||||
"export_error": "Failed to export chat",
|
||||
"export_success": "Chat exported successfully",
|
||||
"features.title": "Features",
|
||||
"integration.mcp.description": "Connect to MCP-compatible services that extend AI capabilities through secure OAuth integration.",
|
||||
"integration.mcp.enabled": "Enable MCP Services",
|
||||
|
|
|
|||
|
|
@ -32,9 +32,6 @@
|
|||
"delete_chat_error": "Chat の削除に失敗しました",
|
||||
"delete_chat_message": "本当に「{{title}}」を削除してもよろしいですか?この操作は元に戻すことはできません。",
|
||||
"delete_chat_success": "Chat が正常に削除されました。",
|
||||
"export_empty_chat": "空の Chat をエクスポートできません",
|
||||
"export_error": "Chat のエクスポートに失敗しました",
|
||||
"export_success": "Chatが正常にエクスポートされました",
|
||||
"features.title": "機能",
|
||||
"integration.mcp.description": "安全なOAuth統合により、AI機能を拡張するMCP対応サービスに接続。",
|
||||
"integration.mcp.enabled": "MCPサービスを有効にする",
|
||||
|
|
|
|||
|
|
@ -32,9 +32,6 @@
|
|||
"delete_chat_error": "删除对话失败",
|
||||
"delete_chat_message": "确定要删除\"{{title}}\"吗?此操作无法撤销。",
|
||||
"delete_chat_success": "对话删除成功",
|
||||
"export_empty_chat": "无法导出空对话",
|
||||
"export_error": "导出对话失败",
|
||||
"export_success": "对话导出成功",
|
||||
"features.title": "功能",
|
||||
"integration.mcp.description": "通过安全的OAuth集成连接到兼容MCP的服务,扩展AI功能。",
|
||||
"integration.mcp.enabled": "启用MCP服务",
|
||||
|
|
|
|||
Loading…
Reference in New Issue