diff --git a/packages/app/src/components/chat/ChatHeader.vue b/packages/app/src/components/chat/ChatHeader.vue index 91324649..a3c211ef 100644 --- a/packages/app/src/components/chat/ChatHeader.vue +++ b/packages/app/src/components/chat/ChatHeader.vue @@ -191,6 +191,12 @@ Plain text (.txt)
+
@@ -210,6 +233,7 @@ import { useChatStore } from '@/stores/chat' import { useAI } from '@/composables/useAI' import { useContentPanel } from '@/composables/useContentPanel' import { downloadConversation, type ExportFormat } from '@/utils/conversation-export' +import { parseImportFile } from '@/utils/conversation-import' defineProps<{ title: string @@ -330,6 +354,44 @@ function handleDelete() { chatStore.deleteConversation(id) showMenu.value = false } + +const importInputRef = ref(null) +const importStatus = ref(null) + +function triggerImport() { + showMenu.value = false + importInputRef.value?.click() +} + +async function handleImportFile(e: Event) { + const input = e.target as HTMLInputElement + const file = input.files?.[0] + if (!file) return + + try { + const text = await file.text() + const result = parseImportFile(text) + + if (result.error || result.conversations.length === 0) { + importStatus.value = `Error: ${result.error ?? 'No conversations found'}` + } else { + for (const conv of result.conversations) { + chatStore.conversations.set(conv.id, conv) + } + const count = result.conversations.length + importStatus.value = `Imported ${count} conversation${count > 1 ? 's' : ''} (${result.format})` + // Switch to first imported conversation + chatStore.setActiveConversation(result.conversations[0].id) + } + } catch { + importStatus.value = 'Error: Failed to read file' + } + + // Clear file input for re-use + input.value = '' + // Auto-hide status after 3 seconds + setTimeout(() => { importStatus.value = null }, 3000) +}