- Filter history to show only items from last 2 hours - Pinned items are always kept regardless of age - Auto-cleanup old unpinned items from database - Increased fetch limit to 50 to ensure enough items for filtering
168 lines
4.2 KiB
TypeScript
168 lines
4.2 KiB
TypeScript
import { ref } from 'vue'
|
|
import { apiCall } from '@/api'
|
|
|
|
export interface HistoryItem {
|
|
id: string
|
|
query: string
|
|
title: string
|
|
chat_state: string | null
|
|
mode: string | null
|
|
pinned: boolean
|
|
created_at: string | null
|
|
updated_at: string | null
|
|
}
|
|
|
|
export function useSearchHistory() {
|
|
const history = ref<HistoryItem[]>([])
|
|
const loading = ref(false)
|
|
const HISTORY_HOURS = 2 // Keep last 2 hours of history
|
|
|
|
async function loadHistory() {
|
|
loading.value = true
|
|
try {
|
|
const result = await apiCall('get_search_history', { limit: 50 })
|
|
const allHistory = Array.isArray(result) ? result : []
|
|
|
|
// Filter to last 2 hours (keep pinned items regardless of age)
|
|
const cutoffTime = Date.now() - (HISTORY_HOURS * 60 * 60 * 1000)
|
|
history.value = allHistory.filter((item: HistoryItem) => {
|
|
if (item.pinned) return true // Always keep pinned items
|
|
if (!item.updated_at) return false
|
|
const itemTime = new Date(item.updated_at).getTime()
|
|
return itemTime >= cutoffTime
|
|
})
|
|
|
|
// Clean up old unpinned items from database
|
|
cleanupOldHistory(cutoffTime)
|
|
} catch (e) {
|
|
console.error('Failed to load history:', e)
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function cleanupOldHistory(cutoffTime: number) {
|
|
try {
|
|
const result = await apiCall('get_search_history', { limit: 100 })
|
|
const allHistory = Array.isArray(result) ? result : []
|
|
for (const item of allHistory) {
|
|
if (item.pinned) continue
|
|
if (!item.updated_at) continue
|
|
const itemTime = new Date(item.updated_at).getTime()
|
|
if (itemTime < cutoffTime) {
|
|
await apiCall('delete_search_history', { id: item.id })
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.error('Failed to cleanup old history:', e)
|
|
}
|
|
}
|
|
|
|
async function saveToHistory(query: string, chatState: string, mode: string) {
|
|
const id = `h_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
|
|
try {
|
|
await apiCall('save_search_history', {
|
|
id,
|
|
query,
|
|
title: query,
|
|
chatState,
|
|
mode,
|
|
})
|
|
await loadHistory()
|
|
} catch (e) {
|
|
console.error('Failed to save history:', e)
|
|
}
|
|
}
|
|
|
|
async function renameHistory(id: string, title: string) {
|
|
try {
|
|
await apiCall('rename_search_history', { id, title })
|
|
await loadHistory()
|
|
} catch (e) {
|
|
console.error('Failed to rename history:', e)
|
|
}
|
|
}
|
|
|
|
async function pinHistory(id: string, pinned: boolean) {
|
|
try {
|
|
await apiCall('pin_search_history', { id, pinned })
|
|
await loadHistory()
|
|
} catch (e) {
|
|
console.error('Failed to pin history:', e)
|
|
}
|
|
}
|
|
|
|
async function deleteHistory(id: string) {
|
|
try {
|
|
await apiCall('delete_search_history', { id })
|
|
await loadHistory()
|
|
} catch (e) {
|
|
console.error('Failed to delete history:', e)
|
|
}
|
|
}
|
|
|
|
function restoreFromHistory(item: HistoryItem): any[] | null {
|
|
if (!item.chat_state) return null
|
|
try {
|
|
return JSON.parse(item.chat_state)
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
return {
|
|
history,
|
|
loading,
|
|
loadHistory,
|
|
saveToHistory,
|
|
renameHistory,
|
|
pinHistory,
|
|
deleteHistory,
|
|
restoreFromHistory,
|
|
}
|
|
}
|
|
|
|
export interface BookmarkItem {
|
|
id: number
|
|
label: string
|
|
history_id: string | null
|
|
created_at: string | null
|
|
}
|
|
|
|
export function useBookmarks() {
|
|
const bookmarks = ref<BookmarkItem[]>([])
|
|
|
|
async function loadBookmarks() {
|
|
try {
|
|
const result = await apiCall('get_bookmarks', {})
|
|
bookmarks.value = Array.isArray(result) ? result : []
|
|
} catch (e) {
|
|
console.error('Failed to load bookmarks:', e)
|
|
}
|
|
}
|
|
|
|
async function saveBookmark(label: string, historyId?: string) {
|
|
try {
|
|
await apiCall('save_bookmark', { label, historyId: historyId || null })
|
|
await loadBookmarks()
|
|
} catch (e) {
|
|
console.error('Failed to save bookmark:', e)
|
|
}
|
|
}
|
|
|
|
async function deleteBookmark(id: number) {
|
|
try {
|
|
await apiCall('delete_bookmark', { id })
|
|
await loadBookmarks()
|
|
} catch (e) {
|
|
console.error('Failed to delete bookmark:', e)
|
|
}
|
|
}
|
|
|
|
return {
|
|
bookmarks,
|
|
loadBookmarks,
|
|
saveBookmark,
|
|
deleteBookmark,
|
|
}
|
|
} |