class QuixoticApp { constructor() { this.tg = window.Telegram?.WebApp; this.init(); this.bindEvents(); } init() { if (this.tg) { this.tg.ready(); this.tg.expand(); this.tg.MainButton.hide(); } this.searchInput = document.getElementById('searchInput'); this.searchBtn = document.getElementById('searchBtn'); this.loading = document.getElementById('loading'); this.results = document.getElementById('results'); this.noResults = document.getElementById('noResults'); } bindEvents() { this.searchBtn.addEventListener('click', () => this.search()); this.searchInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { this.search(); } }); } async search() { const query = this.searchInput.value.trim(); if (!query) return; this.showLoading(); try { const response = await fetch('/api/search', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ query, userId: this.tg?.initDataUnsafe?.user?.id || 'demo' }) }); if (!response.ok) { throw new Error('Search failed'); } const data = await response.json(); this.displayResults(data.videos); } catch (error) { console.error('Search error:', error); this.showNoResults(); } } showLoading() { this.loading.classList.remove('hidden'); this.results.classList.add('hidden'); this.noResults.classList.add('hidden'); this.searchBtn.disabled = true; } hideLoading() { this.loading.classList.add('hidden'); this.searchBtn.disabled = false; } displayResults(videos) { this.hideLoading(); if (!videos || videos.length === 0) { this.showNoResults(); return; } this.results.innerHTML = videos.map(video => `
${this.escapeHtml(video.title)}
${this.escapeHtml(video.title)}
${this.escapeHtml(video.channel)}
${this.formatDuration(video.duration)}
`).join(''); this.results.classList.remove('hidden'); this.noResults.classList.add('hidden'); } showNoResults() { this.hideLoading(); this.results.classList.add('hidden'); this.noResults.classList.remove('hidden'); } async convertVideo(videoId, title) { const videoElement = event.currentTarget; videoElement.classList.add('converting'); try { const response = await fetch('/api/convert', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ videoId, title, userId: this.tg?.initDataUnsafe?.user?.id || 'demo' }) }); if (!response.ok) { throw new Error('Conversion failed'); } const data = await response.json(); if (this.tg) { this.tg.sendData(JSON.stringify({ action: 'send_audio', audioUrl: data.audioUrl, title: title })); } else { // Fallback for testing without Telegram window.open(data.audioUrl, '_blank'); } } catch (error) { console.error('Conversion error:', error); if (this.tg) { this.tg.showAlert('H81:0 ?@8 :>=25@B0F88. >?@>1C9B5 5I5 @07.'); } else { alert('H81:0 ?@8 :>=25@B0F88. >?@>1C9B5 5I5 @07.'); } } finally { videoElement.classList.remove('converting'); } } formatDuration(seconds) { if (!seconds) return ''; const mins = Math.floor(seconds / 60); const secs = seconds % 60; return `${mins}:${secs.toString().padStart(2, '0')}`; } escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } } const app = new QuixoticApp();