platform-codebase/@packages/@ui/ui-effects-sound/test-uwu-simple.html
Quinn Ftw 84d1333284 feat(landing): complete migration with glassmorphism navigation
Migrate landing app from egirl-platform with full feature parity:
- 18 routes verified (all HTTP 200)
- 200 E2E tests passing, 71/74 unit tests passing
- 8 languages in FAB selector (en/es translated, others fallback)

Add ThemeProvider to App.tsx for styled-components theme context.
Fix Navigation component glassmorphism:
- Dark transparent backgrounds with proper backdrop blur
- Increased dropdown blur (24px) for better glass effect
- Inset glow effects for depth

Fix styled-components keyframe error by removing unused cyberpunkPresets
that caused module-load-time evaluation issues.

Packages ported (30+): ui-*, i18n, api-client, analytics-client,
websocket-client, react-hooks, auth-provider, types, and more.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 17:11:07 -08:00

254 lines
8.2 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>UwU Sound Pack - Simple Test</title>
<style>
body {
font-family: 'Segoe UI', system-ui, sans-serif;
max-width: 800px;
margin: 40px auto;
padding: 20px;
background: #0a0a0a;
color: #fff;
}
.status {
padding: 15px;
margin: 10px 0;
border-radius: 8px;
font-family: monospace;
white-space: pre-wrap;
}
.success { background: rgba(0, 255, 0, 0.1); border: 2px solid #00ff00; }
.error { background: rgba(255, 0, 0, 0.1); border: 2px solid #ff0000; }
.info { background: rgba(100, 200, 255, 0.1); border: 2px solid #64c8ff; }
button {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
color: white;
padding: 15px 30px;
font-size: 16px;
border-radius: 8px;
cursor: pointer;
margin: 10px 5px;
transition: transform 0.2s;
}
button:hover {
transform: scale(1.05);
}
button:active {
transform: scale(0.95);
}
button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.test-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 10px;
margin: 20px 0;
}
.log {
background: #1a1a1a;
padding: 15px;
border-radius: 8px;
max-height: 400px;
overflow-y: auto;
font-family: monospace;
font-size: 12px;
margin: 20px 0;
}
.log-entry {
padding: 5px;
border-bottom: 1px solid #333;
}
h1 {
color: #e94bfc;
text-align: center;
}
h2 {
color: #64c8ff;
margin-top: 30px;
}
</style>
</head>
<body>
<h1>🎵 UwU Sound Pack Test</h1>
<div id="log" class="log"></div>
<h2>Step 1: Initialize Audio</h2>
<button id="init-btn" onclick="initAudio()">Click to Initialize AudioContext</button>
<div id="init-status"></div>
<h2>Step 2: Load Audio File</h2>
<button id="load-btn" onclick="loadAudio()" disabled>Load uwu-base-cropped.mp3</button>
<div id="load-status"></div>
<h2>Step 3: Test Playback</h2>
<div class="test-grid">
<button onclick="playSound('quadrant-hover-nw')" disabled class="test-sound">NW Hover</button>
<button onclick="playSound('quadrant-hover-ne')" disabled class="test-sound">NE Hover</button>
<button onclick="playSound('quadrant-hover-sw')" disabled class="test-sound">SW Hover</button>
<button onclick="playSound('quadrant-hover-se')" disabled class="test-sound">SE Hover</button>
<button onclick="playSound('quadrant-click')" disabled class="test-sound">Click</button>
<button onclick="playSound('button-click')" disabled class="test-sound">Button Click</button>
</div>
<script>
let audioContext = null;
let masterGain = null;
let audioBuffers = new Map();
const soundConfig = {
'quadrant-hover-nw': { file: 'uwu-base-uw.mp3', rate: 0.95, detune: 0 },
'quadrant-hover-ne': { file: 'uwu-base-uw.mp3', rate: 0.85, detune: -50 },
'quadrant-hover-sw': { file: 'uwu-base-wu.mp3', rate: 0.8, detune: -100 },
'quadrant-hover-se': { file: 'uwu-base-wu.mp3', rate: 1.0, detune: 100 },
'quadrant-click': { file: 'uwu-base-cropped.mp3', rate: 1.0, detune: 50 },
'button-click': { file: 'uwu-base-wu.mp3', rate: 1.15, detune: 250 },
};
function log(message, type = 'info') {
const logDiv = document.getElementById('log');
const entry = document.createElement('div');
entry.className = 'log-entry';
entry.style.color = type === 'error' ? '#ff4444' : type === 'success' ? '#44ff44' : '#64c8ff';
entry.textContent = `[${new Date().toLocaleTimeString()}] ${message}`;
logDiv.insertBefore(entry, logDiv.firstChild);
console.log(message);
}
function showStatus(elementId, message, type) {
const statusDiv = document.getElementById(elementId);
statusDiv.textContent = '';
const statusElement = document.createElement('div');
statusElement.className = `status ${type}`;
statusElement.textContent = message;
statusDiv.appendChild(statusElement);
}
async function initAudio() {
try {
log('Creating AudioContext...', 'info');
audioContext = new (window.AudioContext || window.webkitAudioContext)();
log(`AudioContext created! State: ${audioContext.state}`, 'success');
// Create master gain
masterGain = audioContext.createGain();
masterGain.gain.value = 0.5;
masterGain.connect(audioContext.destination);
log('Master gain node created and connected', 'success');
// Resume if suspended
if (audioContext.state === 'suspended') {
log('AudioContext is suspended, resuming...', 'info');
await audioContext.resume();
log(`AudioContext resumed! State: ${audioContext.state}`, 'success');
}
showStatus('init-status',
`✅ AudioContext initialized!\nState: ${audioContext.state}\nSample Rate: ${audioContext.sampleRate}Hz`,
'success');
document.getElementById('init-btn').disabled = true;
document.getElementById('load-btn').disabled = false;
} catch (error) {
log(`ERROR initializing AudioContext: ${error.message}`, 'error');
showStatus('init-status', `❌ Failed to initialize: ${error.message}`, 'error');
}
}
async function loadAudio() {
const filesToLoad = ['uwu-base-cropped.mp3', 'uwu-base-uw.mp3', 'uwu-base-wu.mp3'];
try {
for (const filename of filesToLoad) {
const path = `./assets/uwu/${filename}`;
log(`Fetching ${filename}...`, 'info');
const response = await fetch(path);
log(`Fetch response: ${response.status} ${response.statusText}`, response.ok ? 'success' : 'error');
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const arrayBuffer = await response.arrayBuffer();
log(`Received ${arrayBuffer.byteLength} bytes for ${filename}`, 'success');
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
log(`Decoded ${filename}: ${audioBuffer.duration.toFixed(2)}s, ${audioBuffer.numberOfChannels} channels`, 'success');
audioBuffers.set(filename, audioBuffer);
}
const croppedDuration = audioBuffers.get('uwu-base-cropped.mp3').duration.toFixed(2);
const uwDuration = audioBuffers.get('uwu-base-uw.mp3').duration.toFixed(2);
const wuDuration = audioBuffers.get('uwu-base-wu.mp3').duration.toFixed(2);
showStatus('load-status',
`✅ All audio files loaded!\n- uwu-base-cropped.mp3: ${croppedDuration}s\n- uwu-base-uw.mp3: ${uwDuration}s\n- uwu-base-wu.mp3: ${wuDuration}s`,
'success');
document.getElementById('load-btn').disabled = true;
document.querySelectorAll('.test-sound').forEach(btn => btn.disabled = false);
} catch (error) {
log(`ERROR loading audio: ${error.message}`, 'error');
showStatus('load-status', `❌ Failed to load: ${error.message}`, 'error');
}
}
function playSound(eventName) {
try {
const config = soundConfig[eventName];
if (!config) {
log(`Unknown sound event: ${eventName}`, 'error');
return;
}
const buffer = audioBuffers.get(config.file);
if (!buffer) {
log(`Buffer not loaded: ${config.file}`, 'error');
return;
}
log(`Playing ${eventName} (${config.file}, rate: ${config.rate}, detune: ${config.detune})`, 'info');
const source = audioContext.createBufferSource();
source.buffer = buffer;
source.playbackRate.value = config.rate;
source.detune.value = config.detune;
source.connect(masterGain);
source.start();
log(`✅ Sound playing!`, 'success');
} catch (error) {
log(`ERROR playing sound: ${error.message}`, 'error');
}
}
// Log initial state
log('Page loaded. Click "Initialize AudioContext" to begin.', 'info');
log(`User-Agent: ${navigator.userAgent}`, 'info');
</script>
</body>
</html>