Created
May 5, 2025 05:27
-
-
Save ElDuderino420/a883b427cffedcbf1276c12b6b3716d7 to your computer and use it in GitHub Desktop.
HTML Soundboard Fuzzy Finder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # PowerShell script to create fuzzy-finder.js and attach it to index.html | |
| # Path variables | |
| $htmlFilePath = "$PSScriptRoot\index.html" | |
| $jsFilePath = "$PSScriptRoot\fuzzy-finder.js" | |
| # Check if the HTML file exists | |
| if (-not (Test-Path $htmlFilePath)) { | |
| Write-Error "index.html not found at $htmlFilePath" | |
| exit 1 | |
| } | |
| # Function to create the fuzzy-finder.js file | |
| function Create-FuzzyFinderJs { | |
| $fuzzyFinderContent = @' | |
| /** | |
| * Soundboard Fuzzy Finder | |
| * Listens for SHIFT+P and opens a fuzzy search bar for sound selection | |
| */ | |
| (function() { | |
| // Create all necessary DOM elements for the fuzzy finder | |
| const fuzzyFinderContainer = document.createElement('div'); | |
| fuzzyFinderContainer.id = 'fuzzy-finder-container'; | |
| fuzzyFinderContainer.style.cssText = ` | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background-color: rgba(0, 0, 0, 0.7); | |
| z-index: 9999; | |
| display: none; | |
| flex-direction: column; | |
| align-items: center; | |
| padding-top: 100px; | |
| `; | |
| const searchBox = document.createElement('input'); | |
| searchBox.id = 'fuzzy-finder-search'; | |
| searchBox.type = 'text'; | |
| searchBox.placeholder = 'Search sounds...'; | |
| searchBox.style.cssText = ` | |
| width: 80%; | |
| max-width: 600px; | |
| padding: 12px; | |
| font-size: 18px; | |
| border: none; | |
| border-radius: 4px; | |
| margin-bottom: 10px; | |
| `; | |
| const resultsList = document.createElement('div'); | |
| resultsList.id = 'fuzzy-finder-results'; | |
| resultsList.style.cssText = ` | |
| width: 80%; | |
| max-width: 600px; | |
| max-height: 70vh; | |
| overflow-y: auto; | |
| background-color: white; | |
| border-radius: 4px; | |
| `; | |
| fuzzyFinderContainer.appendChild(searchBox); | |
| fuzzyFinderContainer.appendChild(resultsList); | |
| document.body.appendChild(fuzzyFinderContainer); | |
| // Initialize sound data for fuzzy search | |
| const soundItems = []; | |
| document.querySelectorAll('.sound').forEach(element => { | |
| soundItems.push({ | |
| id: element.id, | |
| name: element.textContent.trim(), | |
| element: element | |
| }); | |
| }); | |
| // Fuzzy search function | |
| function fuzzySearch(query, items) { | |
| query = query.toLowerCase(); | |
| return items.filter(item => { | |
| const name = item.name.toLowerCase(); | |
| return name.includes(query); | |
| }).sort((a, b) => { | |
| const aName = a.name.toLowerCase(); | |
| const bName = b.name.toLowerCase(); | |
| const aStartsWithQuery = aName.startsWith(query); | |
| const bStartsWithQuery = bName.startsWith(query); | |
| if (aStartsWithQuery && !bStartsWithQuery) return -1; | |
| if (!aStartsWithQuery && bStartsWithQuery) return 1; | |
| return aName.localeCompare(bName); | |
| }); | |
| } | |
| // Show fuzzy finder | |
| function showFuzzyFinder() { | |
| fuzzyFinderContainer.style.display = 'flex'; | |
| searchBox.value = ''; | |
| searchBox.focus(); | |
| updateResults(''); | |
| } | |
| // Hide fuzzy finder | |
| function hideFuzzyFinder() { | |
| fuzzyFinderContainer.style.display = 'none'; | |
| } | |
| // Update search results | |
| function updateResults(query) { | |
| const results = fuzzySearch(query, soundItems); | |
| resultsList.innerHTML = ''; | |
| results.forEach((item, index) => { | |
| const resultItem = document.createElement('div'); | |
| resultItem.className = 'fuzzy-finder-result'; | |
| resultItem.dataset.id = item.id; | |
| resultItem.dataset.index = index; | |
| resultItem.textContent = item.name; | |
| resultItem.style.cssText = ` | |
| padding: 8px 12px; | |
| cursor: pointer; | |
| border-bottom: 1px solid #eee; | |
| `; | |
| resultItem.addEventListener('click', () => { | |
| playSelectedSound(item.id); | |
| hideFuzzyFinder(); | |
| }); | |
| resultItem.addEventListener('mouseover', () => { | |
| selectResult(index); | |
| }); | |
| resultsList.appendChild(resultItem); | |
| }); | |
| if (results.length > 0) { | |
| selectResult(0); | |
| } | |
| } | |
| // Select a result item by index | |
| let selectedIndex = 0; | |
| function selectResult(index) { | |
| document.querySelectorAll('.fuzzy-finder-result').forEach(el => { | |
| el.style.backgroundColor = ''; | |
| el.style.color = ''; | |
| }); | |
| const selected = document.querySelector(`.fuzzy-finder-result[data-index="${index}"]`); | |
| if (selected) { | |
| selected.style.backgroundColor = '#4a90e2'; | |
| selected.style.color = 'white'; | |
| selectedIndex = index; | |
| // Ensure the selected item is visible | |
| if (selected.offsetTop < resultsList.scrollTop) { | |
| resultsList.scrollTop = selected.offsetTop; | |
| } else if (selected.offsetTop + selected.offsetHeight > resultsList.scrollTop + resultsList.clientHeight) { | |
| resultsList.scrollTop = selected.offsetTop + selected.offsetHeight - resultsList.clientHeight; | |
| } | |
| } | |
| } | |
| // Play the selected sound | |
| function playSelectedSound(id) { | |
| if (typeof playSound === 'function') { | |
| playSound(id); | |
| } else { | |
| console.error('playSound function not found'); | |
| } | |
| } | |
| // Handle keyboard navigation | |
| searchBox.addEventListener('keydown', (e) => { | |
| const results = document.querySelectorAll('.fuzzy-finder-result'); | |
| switch (e.key) { | |
| case 'ArrowDown': | |
| e.preventDefault(); | |
| selectResult((selectedIndex + 1) % results.length); | |
| break; | |
| case 'ArrowUp': | |
| e.preventDefault(); | |
| selectResult((selectedIndex - 1 + results.length) % results.length); | |
| break; | |
| case 'Enter': | |
| e.preventDefault(); | |
| const selected = document.querySelector(`.fuzzy-finder-result[data-index="${selectedIndex}"]`); | |
| if (selected) { | |
| playSelectedSound(selected.dataset.id); | |
| hideFuzzyFinder(); | |
| } | |
| break; | |
| case 'Escape': | |
| e.preventDefault(); | |
| hideFuzzyFinder(); | |
| break; | |
| } | |
| }); | |
| // Handle search input | |
| searchBox.addEventListener('input', (e) => { | |
| updateResults(e.target.value); | |
| selectedIndex = 0; | |
| }); | |
| // Click outside to close | |
| fuzzyFinderContainer.addEventListener('click', (e) => { | |
| if (e.target === fuzzyFinderContainer) { | |
| hideFuzzyFinder(); | |
| } | |
| }); | |
| // Global key handler for SHIFT+P (case insensitive) | |
| document.addEventListener('keydown', (e) => { | |
| if ((e.key === 'P' || e.key === 'p') && e.shiftKey) { | |
| e.preventDefault(); | |
| showFuzzyFinder(); | |
| } | |
| }); | |
| // Add some hover effects for result items | |
| const style = document.createElement('style'); | |
| style.textContent = ` | |
| .fuzzy-finder-result:hover { | |
| background-color: #f0f0f0; | |
| } | |
| `; | |
| document.head.appendChild(style); | |
| })(); | |
| '@ | |
| # Create the JS file | |
| $fuzzyFinderContent | Out-File -FilePath $jsFilePath -Encoding utf8 | |
| Write-Host "Created fuzzy-finder.js at $jsFilePath" | |
| } | |
| # Function to check if the script tag is already in the HTML file | |
| function Check-ScriptTagExists { | |
| $htmlContent = Get-Content $htmlFilePath -Raw | |
| return $htmlContent -match '<script.*src="fuzzy-finder.js".*>' | |
| } | |
| # Function to add the script tag to the HTML file | |
| function Add-ScriptTag { | |
| $htmlContent = Get-Content $htmlFilePath -Raw | |
| # Add the script tag before the closing head tag | |
| $newHtmlContent = $htmlContent -replace '</head>', ' <script type="text/javascript" src="fuzzy-finder.js" defer></script> | |
| </head>' | |
| # Write the updated content back to the file | |
| $newHtmlContent | Out-File -FilePath $htmlFilePath -Encoding utf8 | |
| Write-Host "Added script tag to index.html" | |
| } | |
| # Main execution | |
| Write-Host "Starting fuzzy-finder setup process..." | |
| # Create the JS file (or overwrite if it exists) | |
| Create-FuzzyFinderJs | |
| # Check if the script tag already exists in the HTML | |
| if (Check-ScriptTagExists) { | |
| Write-Host "Script tag for fuzzy-finder.js already exists in index.html" | |
| } else { | |
| # Add the script tag to the HTML | |
| Add-ScriptTag | |
| } | |
| Write-Host "Setup complete! Fuzzy-finder has been installed." | |
| Write-Host "Press SHIFT+P while viewing the soundboard to use the fuzzy finder." | |
| # Wait for user to press a key before exiting | |
| Write-Host " | |
| Press any key to exit..." -NoNewline | |
| $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment