From 94bb78346fe8d7a8b482001382f4ec9d52e7c6d1 Mon Sep 17 00:00:00 2001 From: FragginWagon Date: Wed, 28 Jan 2026 20:35:40 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=8D=20Add=20web=20worker=20for=20searc?= =?UTF-8?q?h=20operations=20to=20improve=20performance=20and=20handle=20se?= =?UTF-8?q?arch=20progress=20and=20results?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/GamemasterExplorer.vue | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/code/websites/pokedex.online/src/views/GamemasterExplorer.vue b/code/websites/pokedex.online/src/views/GamemasterExplorer.vue index ff251d9..e29d4f7 100644 --- a/code/websites/pokedex.online/src/views/GamemasterExplorer.vue +++ b/code/websites/pokedex.online/src/views/GamemasterExplorer.vue @@ -396,7 +396,43 @@ const preferences = useLocalStorage('gamemaster-explorer-prefs', { const clipboard = useClipboard(); const client = new GamemasterClient(); -// Computed +// Web Worker for search operations +let searchWorker = null; +let searchWorkerRequestId = 0; +const initSearchWorker = () => { + if (!searchWorker) { + searchWorker = new Worker( + new URL('../workers/search.worker.js', import.meta.url), + { type: 'module' } + ); + searchWorker.onmessage = handleSearchWorkerMessage; + } +}; + +const handleSearchWorkerMessage = (event) => { + const { type, id, results, percent, error: workerError } = event.data; + + if (type === 'progress') { + operationProgress.value.percent = percent; + operationProgress.value.message = `Searching... ${Math.round(percent)}%`; + } else if (type === 'complete') { + searchResults.value = results; + currentResultIndex.value = 0; + operationProgress.value.complete = true; + setTimeout(() => { + operationProgress.value.active = false; + }, 500); + // Scroll to first result if found + if (results.length > 0) { + nextTick(() => scrollToResult()); + } + } else if (type === 'error') { + console.error('Search worker error:', workerError); + operationProgress.value.active = false; + } +}; + +// Composables const hasFiles = computed(() => status.value.totalFiles > 0); const fileTooLarge = computed(() => fileLines.value.length > 10000); const lineHeight = computed(() => {