|
1 | | -// Dark mode functionality |
2 | | -function toggleDarkMode() { |
3 | | - const body = document.body; |
4 | | - const toggle = document.querySelector(".dark-mode-toggle"); |
5 | | - const sunIcon = toggle.querySelector(".sun-icon"); |
6 | | - const moonIcon = toggle.querySelector(".moon-icon"); |
7 | | - |
8 | | - body.classList.toggle("dark-mode"); |
9 | | - const isDarkMode = body.classList.contains("dark-mode"); |
10 | | - |
11 | | - localStorage.setItem("dark-mode", isDarkMode); |
12 | | - sunIcon.style.display = isDarkMode ? "none" : "block"; |
13 | | - moonIcon.style.display = isDarkMode ? "block" : "none"; |
14 | | -} |
| 1 | +// Dark mode functionality - using shared utility |
| 2 | +// toggleDarkMode is now imported from shared-utils.js |
15 | 3 |
|
16 | 4 | // Add these new functions at the top |
17 | 5 | function extractVariables(text) { |
@@ -268,35 +256,7 @@ function updatePromptCount(filteredCount, totalCount) { |
268 | 256 | } |
269 | 257 | } |
270 | 258 |
|
271 | | -function parseCSV(csv) { |
272 | | - const lines = csv.split("\n"); |
273 | | - const headers = lines[0] |
274 | | - .split(",") |
275 | | - .map((header) => header.replace(/"/g, "").trim()); |
276 | | - |
277 | | - return lines |
278 | | - .slice(1) |
279 | | - .map((line) => { |
280 | | - const values = line.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g) || []; |
281 | | - const entry = {}; |
282 | | - |
283 | | - headers.forEach((header, index) => { |
284 | | - let value = values[index] ? values[index].replace(/"/g, "").trim() : ""; |
285 | | - // Remove backticks from the act/title |
286 | | - if (header === "act") { |
287 | | - value = value.replace(/`/g, ""); |
288 | | - } |
289 | | - // Convert 'TRUE'/'FALSE' strings to boolean for for_devs |
290 | | - if (header === "for_devs") { |
291 | | - value = value.toUpperCase() === "TRUE"; |
292 | | - } |
293 | | - entry[header] = value; |
294 | | - }); |
295 | | - |
296 | | - return entry; |
297 | | - }) |
298 | | - .filter((entry) => entry.act && entry.prompt); |
299 | | -} |
| 259 | +// parseCSV is now imported from shared-utils.js |
300 | 260 |
|
301 | 261 | function displaySearchResults(results) { |
302 | 262 | const searchResults = document.getElementById("searchResults"); |
@@ -336,76 +296,13 @@ function displaySearchResults(results) { |
336 | 296 | li.className = "search-result-item"; |
337 | 297 | li.textContent = result.act; |
338 | 298 | li.addEventListener("click", () => { |
339 | | - // Find the prompt card with matching title |
340 | | - const cards = document.querySelectorAll(".prompt-card"); |
341 | | - const targetCard = Array.from(cards).find((card) => { |
342 | | - const cardTitle = card |
343 | | - .querySelector(".prompt-title") |
344 | | - .textContent.replace(/\s+/g, " ") // Normalize whitespace |
345 | | - .replace(/[\n\r]/g, "") // Remove newlines |
346 | | - .trim(); |
347 | | - |
348 | | - const searchTitle = result.act |
349 | | - .replace(/\s+/g, " ") // Normalize whitespace |
350 | | - .replace(/[\n\r]/g, "") // Remove newlines |
351 | | - .trim(); |
352 | | - |
353 | | - return ( |
354 | | - cardTitle.toLowerCase().includes(searchTitle.toLowerCase()) || |
355 | | - searchTitle.toLowerCase().includes(cardTitle.toLowerCase()) |
356 | | - ); |
357 | | - }); |
| 299 | + // Find the prompt card with matching title using shared utility |
| 300 | + const targetCard = findPromptCardByTitle(result.act); |
358 | 301 |
|
359 | 302 | if (targetCard) { |
360 | | - // Remove highlight from all cards |
361 | | - cards.forEach((card) => { |
362 | | - card.style.transition = "all 0.3s ease"; |
363 | | - card.style.transform = "none"; |
364 | | - card.style.boxShadow = "none"; |
365 | | - card.style.borderColor = ""; |
366 | | - }); |
367 | | - |
368 | | - // Different scroll behavior for mobile and desktop |
369 | 303 | const isMobile = window.innerWidth <= 768; |
370 | | - const headerHeight = |
371 | | - document.querySelector(".site-header").offsetHeight; |
372 | | - |
373 | | - if (isMobile) { |
374 | | - // On mobile, scroll the window |
375 | | - const cardRect = targetCard.getBoundingClientRect(); |
376 | | - const scrollTop = |
377 | | - window.pageYOffset + cardRect.top - headerHeight - 50; |
378 | | - |
379 | | - window.scrollTo({ |
380 | | - top: scrollTop, |
381 | | - behavior: "smooth", |
382 | | - }); |
383 | | - } else { |
384 | | - // On desktop, scroll the main-content container |
385 | | - const mainContent = document.querySelector(".main-content"); |
386 | | - const cardRect = targetCard.getBoundingClientRect(); |
387 | | - const scrollTop = |
388 | | - mainContent.scrollTop + cardRect.top - headerHeight - 50; |
389 | | - |
390 | | - mainContent.scrollTo({ |
391 | | - top: scrollTop, |
392 | | - behavior: "smooth", |
393 | | - }); |
394 | | - } |
395 | | - |
396 | | - // Add highlight effect after scrolling completes |
397 | | - setTimeout(() => { |
398 | | - targetCard.style.transform = "scale(1.02)"; |
399 | | - targetCard.style.boxShadow = "0 0 0 2px var(--accent-color)"; |
400 | | - targetCard.style.borderColor = "var(--accent-color)"; |
401 | | - |
402 | | - // Remove highlight after animation |
403 | | - setTimeout(() => { |
404 | | - targetCard.style.transform = "none"; |
405 | | - targetCard.style.boxShadow = "none"; |
406 | | - targetCard.style.borderColor = ""; |
407 | | - }, 2000); |
408 | | - }, 500); // Wait for scroll to complete |
| 304 | + const headerHeight = document.querySelector(".site-header").offsetHeight; |
| 305 | + scrollToPromptCard(targetCard, isMobile, headerHeight); |
409 | 306 | } else { |
410 | 307 | console.log("Card not found for:", result.act); |
411 | 308 | } |
@@ -454,14 +351,8 @@ function filterPrompts() { |
454 | 351 | cards.forEach((card) => { |
455 | 352 | const title = card.querySelector(".prompt-title").textContent.trim(); |
456 | 353 | const matchingPrompt = prompts.find((p) => { |
457 | | - const pTitle = p.act |
458 | | - .replace(/\s+/g, " ") |
459 | | - .replace(/[\n\r]/g, "") |
460 | | - .trim(); |
461 | | - const cardTitle = title |
462 | | - .replace(/\s+/g, " ") |
463 | | - .replace(/[\n\r]/g, "") |
464 | | - .trim(); |
| 354 | + const pTitle = normalizeText(p.act); |
| 355 | + const cardTitle = normalizeText(title); |
465 | 356 | return ( |
466 | 357 | pTitle.toLowerCase() === cardTitle.toLowerCase() || |
467 | 358 | pTitle.toLowerCase().includes(cardTitle.toLowerCase()) || |
@@ -524,14 +415,8 @@ function createPromptCards() { |
524 | 415 |
|
525 | 416 | // Find matching prompt in CSV |
526 | 417 | const matchingPrompt = prompts.find((p) => { |
527 | | - const csvTitle = p.act |
528 | | - .replace(/\s+/g, " ") |
529 | | - .replace(/[\n\r]/g, "") |
530 | | - .trim(); |
531 | | - const elementTitle = title |
532 | | - .replace(/\s+/g, " ") |
533 | | - .replace(/[\n\r]/g, "") |
534 | | - .trim(); |
| 418 | + const csvTitle = normalizeText(p.act); |
| 419 | + const elementTitle = normalizeText(title); |
535 | 420 | return ( |
536 | 421 | csvTitle.toLowerCase() === elementTitle.toLowerCase() || |
537 | 422 | csvTitle.toLowerCase().includes(elementTitle.toLowerCase()) || |
|
0 commit comments