性能优化
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, onUnmounted, nextTick, watch } from 'vue'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import { listen, type UnlistenFn } from '@tauri-apps/api/event'
|
||||
import { getCurrentWindow, Effect, EffectState } from '@tauri-apps/api/window'
|
||||
// Rust 端通过 tauri-specta 生成的命令绑定(bindings.ts)
|
||||
import { commands } from '@/lib/bindings'
|
||||
import { Search, Command, Loader2, CornerDownLeft, Calculator, Globe, Lock, ChevronRight, Terminal, History, FolderOpen, Ruler, Trash2 } from '@lucide/vue'
|
||||
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@/components/ui/accordion'
|
||||
import { aggregateSearch, loadAppIconsForResults, recordHistoryItem, getMoreHistoryItems, getMoreHistoryCount, setFileIndexReady, type QPItem, type QPSubAction } from './providers'
|
||||
import { EVENTS, STORAGE_KEYS } from '@/lib/constants'
|
||||
|
||||
// ===== 状态 =====
|
||||
const query = ref('')
|
||||
@@ -29,7 +31,7 @@ const moreHistoryItems = ref<QPItem[]>([])
|
||||
const moreHistoryCount = ref(0)
|
||||
|
||||
// ===== 历史频率(localStorage 持久化,用于排序加权) =====
|
||||
const HISTORY_KEY = 'thing_quickpanel_history'
|
||||
const HISTORY_KEY = STORAGE_KEYS.quickpanelHistory
|
||||
|
||||
function loadHistory(): Record<string, number> {
|
||||
try {
|
||||
@@ -61,11 +63,17 @@ function applyHistoryBoost(items: QPItem[]): QPItem[] {
|
||||
}
|
||||
|
||||
// ===== 搜索 =====
|
||||
/** 搜索请求序号:每次 doSearch 自增,过期请求(序号落后)结果直接丢弃,防止慢请求覆盖新结果 */
|
||||
let searchSeq = 0
|
||||
|
||||
async function doSearch() {
|
||||
const seq = ++searchSeq
|
||||
const q = query.value.trim()
|
||||
if (!q) {
|
||||
// 空查询:显示命令快捷入口 + 系统操作 + 历史(置顶3条)
|
||||
results.value = applyHistoryBoost(await aggregateSearch(''))
|
||||
const items = await aggregateSearch('')
|
||||
if (seq !== searchSeq) return // 过期请求丢弃
|
||||
results.value = applyHistoryBoost(items)
|
||||
selectedIndex.value = 0
|
||||
// 加载更多历史(Accordion 折叠区,不参与键盘导航)
|
||||
moreHistoryItems.value = getMoreHistoryItems()
|
||||
@@ -81,15 +89,18 @@ async function doSearch() {
|
||||
loading.value = true
|
||||
try {
|
||||
const items = await aggregateSearch(q)
|
||||
if (seq !== searchSeq) return // 过期请求丢弃,不覆盖新结果
|
||||
results.value = applyHistoryBoost(items)
|
||||
selectedIndex.value = 0
|
||||
// 后台加载应用图标(不阻塞结果显示)
|
||||
void loadAppIconsForResults(results.value)
|
||||
} catch (e) {
|
||||
if (seq !== searchSeq) return
|
||||
console.error('[quickpanel] 搜索失败:', e)
|
||||
results.value = []
|
||||
} finally {
|
||||
loading.value = false
|
||||
// 仅最新请求可结束 loading,避免旧请求提前清除新请求的加载态
|
||||
if (seq === searchSeq) loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +114,7 @@ watch(query, () => {
|
||||
// ===== 执行与隐藏 =====
|
||||
async function hideWindow() {
|
||||
try {
|
||||
await invoke('quickpanel_hide_popup')
|
||||
await commands.quickpanelHidePopup()
|
||||
} catch {
|
||||
/* 忽略 */
|
||||
}
|
||||
@@ -145,7 +156,7 @@ async function confirmDelete() {
|
||||
if (!pd) return
|
||||
pendingDelete.value = null
|
||||
try {
|
||||
await invoke('quickpanel_delete_file', { path: pd.path })
|
||||
await commands.quickpanelDeleteFile(pd.path)
|
||||
} catch (e) {
|
||||
console.error('[quickpanel] 删除失败:', e)
|
||||
}
|
||||
@@ -294,7 +305,7 @@ const hasResults = () => results.value.length > 0
|
||||
// ===== 主题应用(与主应用同步,独立窗口需自行设置) =====
|
||||
function readMainTheme(): { theme: string; effect: string } {
|
||||
try {
|
||||
const raw = localStorage.getItem('thing_app_settings')
|
||||
const raw = localStorage.getItem(STORAGE_KEYS.appSettings)
|
||||
if (raw) {
|
||||
const s = JSON.parse(raw)
|
||||
return {
|
||||
@@ -372,13 +383,13 @@ onMounted(async () => {
|
||||
unlistenFns.push(() => mq.removeEventListener('change', onThemeChange))
|
||||
|
||||
const onStorage = (e: StorageEvent) => {
|
||||
if (e.key === 'thing_app_settings') applyTheme()
|
||||
if (e.key === STORAGE_KEYS.appSettings) applyTheme()
|
||||
}
|
||||
window.addEventListener('storage', onStorage)
|
||||
unlistenFns.push(() => window.removeEventListener('storage', onStorage))
|
||||
|
||||
// 监听弹窗显示事件:重新同步主题 + 清空输入 + 加载初始结果
|
||||
unlistenFns.push(await listen('quickpanel-show', async () => {
|
||||
unlistenFns.push(await listen(EVENTS.quickpanelShow, async () => {
|
||||
await applyTheme()
|
||||
query.value = ''
|
||||
await doSearch()
|
||||
@@ -386,7 +397,7 @@ onMounted(async () => {
|
||||
inputRef.value?.focus()
|
||||
}))
|
||||
|
||||
unlistenFns.push(await listen('quickpanel-hide', () => {
|
||||
unlistenFns.push(await listen(EVENTS.quickpanelHide, () => {
|
||||
query.value = ''
|
||||
results.value = []
|
||||
}))
|
||||
@@ -394,7 +405,7 @@ onMounted(async () => {
|
||||
// 初始加载(空查询显示快捷入口)
|
||||
// 独立窗口需自行检查文件索引状态(主窗口的 setFileIndexReady 不共享到此上下文)
|
||||
try {
|
||||
const stats = await invoke<{ total: number }>('quickpanel_file_index_stats')
|
||||
const stats = await commands.quickpanelFileIndexStats()
|
||||
setFileIndexReady((stats?.total ?? 0) > 0)
|
||||
} catch {
|
||||
/* 索引未初始化,忽略 */
|
||||
@@ -404,7 +415,7 @@ onMounted(async () => {
|
||||
inputRef.value?.focus()
|
||||
|
||||
try {
|
||||
await invoke('quickpanel_show_window')
|
||||
await commands.quickpanelShowWindow()
|
||||
} catch {
|
||||
/* 忽略 */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user