feat(chat): enhance chat functionality with song integration and UI improvements
- Updated ChatHeader and ChatMessage components to support song selection and display. - Enhanced useContentPanel to handle both film and song content, allowing for richer interactions. - Improved FilmCard and added SongCard components for better media representation. - Refactored environment variables for better configuration management. - Updated .gitignore to include development chat history. Made-with: Cursor
This commit is contained in:
@@ -2,18 +2,87 @@ import { defineStore } from 'pinia'
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import type { Message, Conversation } from '@aiui/core/types/message'
|
||||
|
||||
const isDev = import.meta.env.DEV
|
||||
let saveTimer: ReturnType<typeof setTimeout> | null = null
|
||||
const SAVE_DEBOUNCE = 800
|
||||
|
||||
// Server-side persistence via Vite dev middleware
|
||||
async function loadServerChats(): Promise<{ conversations: Map<string, Conversation>; activeId: string | null }> {
|
||||
const empty = { conversations: new Map<string, Conversation>(), activeId: null }
|
||||
if (!isDev) return empty
|
||||
try {
|
||||
const res = await fetch('/api/dev-chats')
|
||||
if (!res.ok) return empty
|
||||
const data = await res.json() as {
|
||||
conversations?: Record<string, Conversation>
|
||||
activeConversationId?: string | null
|
||||
}
|
||||
if (!data.conversations) return empty
|
||||
const conversations = new Map(Object.entries(data.conversations))
|
||||
return {
|
||||
conversations,
|
||||
activeId: data.activeConversationId ?? null,
|
||||
}
|
||||
} catch {
|
||||
return empty
|
||||
}
|
||||
}
|
||||
|
||||
let _loaded = false
|
||||
|
||||
function saveServerChats(conversations: Map<string, Conversation>, activeId: string | null) {
|
||||
if (!isDev || !_loaded) return
|
||||
if (saveTimer) clearTimeout(saveTimer)
|
||||
saveTimer = setTimeout(() => {
|
||||
const obj = Object.fromEntries(conversations)
|
||||
fetch('/api/dev-chats', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ conversations: obj, activeConversationId: activeId }),
|
||||
}).catch(() => {})
|
||||
}, SAVE_DEBOUNCE)
|
||||
}
|
||||
|
||||
export const useChatStore = defineStore('chat', () => {
|
||||
const conversations = ref<Map<string, Conversation>>(new Map())
|
||||
const activeConversationId = ref<string | null>(null)
|
||||
const isStreaming = ref(false)
|
||||
const loaded = ref(false)
|
||||
|
||||
const savedSide = localStorage.getItem('aiui-panel-side') as 'left' | 'right' | null
|
||||
const panelSide = ref<'left' | 'right'>(savedSide ?? 'right')
|
||||
|
||||
// Load chats from server on startup — _loaded gate prevents the watcher
|
||||
// from overwriting the file with empty data before the load completes
|
||||
if (isDev) {
|
||||
loadServerChats().then((data) => {
|
||||
if (data.conversations.size > 0) {
|
||||
conversations.value = data.conversations
|
||||
activeConversationId.value =
|
||||
data.activeId && data.conversations.has(data.activeId)
|
||||
? data.activeId
|
||||
: [...data.conversations.keys()][0] ?? null
|
||||
}
|
||||
loaded.value = true
|
||||
_loaded = true
|
||||
})
|
||||
} else {
|
||||
loaded.value = true
|
||||
_loaded = true
|
||||
}
|
||||
|
||||
watch(panelSide, (val) => {
|
||||
localStorage.setItem('aiui-panel-side', val)
|
||||
})
|
||||
|
||||
watch(
|
||||
[conversations, activeConversationId],
|
||||
([conv, active]) => {
|
||||
saveServerChats(conv as Map<string, Conversation>, active as string | null)
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
const activeConversation = computed(() => {
|
||||
if (!activeConversationId.value) return null
|
||||
return conversations.value.get(activeConversationId.value) ?? null
|
||||
@@ -90,6 +159,7 @@ export const useChatStore = defineStore('chat', () => {
|
||||
messages,
|
||||
conversationList,
|
||||
isStreaming,
|
||||
loaded,
|
||||
panelSide,
|
||||
createConversation,
|
||||
addMessage,
|
||||
|
||||
Reference in New Issue
Block a user