Skip to content

Instantly share code, notes, and snippets.

@ElDuderino420
Created May 5, 2025 05:27
Show Gist options
  • Select an option

  • Save ElDuderino420/a883b427cffedcbf1276c12b6b3716d7 to your computer and use it in GitHub Desktop.

Select an option

Save ElDuderino420/a883b427cffedcbf1276c12b6b3716d7 to your computer and use it in GitHub Desktop.
HTML Soundboard Fuzzy Finder
# 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