// kryz-go app entry point window.addEventListener('DOMContentLoaded', () => { console.log('kryz-go loaded'); initializeStreamPlayer(); initializeBackgroundMode(); }); function initializeStreamPlayer() { const streamUrl = 'https://kryz.out.airtime.pro/kryz_b'; const audio = document.getElementById('stream-player'); const startButton = document.getElementById('start-stream'); const stopButton = document.getElementById('stop-stream'); const status = document.getElementById('stream-status'); if (!audio || !startButton || !stopButton || !status) { console.error('Stream player controls are missing from the page.'); return; } const setStatus = (isPlaying, text) => { startButton.disabled = isPlaying; stopButton.disabled = !isPlaying; status.textContent = text; }; const ensureBackgroundPlaybackPermissions = async () => { const backgroundMode = window.Capacitor?.Plugins?.BackgroundMode; if (!backgroundMode) { return true; } const microphonePermission = await backgroundMode.checkMicrophonePermission(); if (microphonePermission.microphone === 'granted') { return true; } const requestedMicrophonePermission = await backgroundMode.requestMicrophonePermission(); if (requestedMicrophonePermission.microphone === 'granted') { return true; } setStatus(false, 'Enable microphone permission in Android settings for screen-off playback.'); console.warn('Background playback blocked: microphone permission not granted.'); return false; }; const startStream = async () => { try { const hasBackgroundPermissions = await ensureBackgroundPlaybackPermissions(); if (!hasBackgroundPermissions) { return; } audio.src = streamUrl; await audio.play(); setStatus(true, 'Stream is playing.'); } catch (error) { setStatus(false, 'Unable to start stream.'); console.error('Failed to start stream:', error); } }; const stopStream = () => { audio.pause(); audio.removeAttribute('src'); audio.load(); setStatus(false, 'Stream is stopped.'); }; startButton.addEventListener('click', startStream); stopButton.addEventListener('click', stopStream); audio.addEventListener('ended', () => { setStatus(false, 'Stream ended.'); }); audio.addEventListener('error', () => { setStatus(false, 'Stream error.'); }); } async function initializeBackgroundMode() { const backgroundMode = window.Capacitor?.Plugins?.BackgroundMode; if (!backgroundMode) { console.warn('BackgroundMode plugin is not available in this runtime.'); return; } try { const notificationPermission = await backgroundMode.checkNotificationsPermission(); if (notificationPermission.notifications !== 'granted') { await backgroundMode.requestNotificationsPermission(); } const microphonePermission = await backgroundMode.checkMicrophonePermission(); if (microphonePermission.microphone !== 'granted') { const requestedMicrophonePermission = await backgroundMode.requestMicrophonePermission(); if (requestedMicrophonePermission.microphone !== 'granted') { console.warn('BackgroundMode microphone permission denied; background playback may stop when screen is off.'); } } const batteryOptimizations = await backgroundMode.checkBatteryOptimizations(); if (batteryOptimizations.enabled) { console.warn('Battery optimizations are enabled; requesting exemption for reliable background playback.'); await backgroundMode.requestDisableBatteryOptimizations(); } await backgroundMode.disableWebViewOptimizations(); await backgroundMode.enable({ title: 'KRYZ-Go!', text: 'Background mode is active', channelName: 'kryz-go background', channelDescription: 'Keeps kryz-go running while the app is in background', resume: true, silent: false, disableWebViewOptimization: true, }); await backgroundMode.addListener('appInBackground', () => { console.log('kryz-go moved to background'); }); await backgroundMode.addListener('appInForeground', () => { console.log('kryz-go returned to foreground'); }); console.log('BackgroundMode plugin enabled.'); } catch (error) { console.error('Failed to initialize BackgroundMode plugin:', error); } }