first step
This commit is contained in:
64
src/main.js
64
src/main.js
@@ -7,7 +7,10 @@ let currentIndex = 0;
|
||||
let isPlaying = false;
|
||||
let currentMode = 'local'; // 'local' | 'cast'
|
||||
let currentCastDevice = null;
|
||||
const audio = new Audio();
|
||||
|
||||
// Local playback is handled natively by the Tauri backend (player_* commands).
|
||||
// The WebView is a control surface only.
|
||||
let localPlayerPollId = null;
|
||||
|
||||
// UI Elements
|
||||
const stationNameEl = document.getElementById('station-name');
|
||||
@@ -95,7 +98,9 @@ function restoreSavedVolume() {
|
||||
volumeSlider.value = String(saved);
|
||||
volumeValue.textContent = `${saved}%`;
|
||||
const decimals = saved / 100;
|
||||
audio.volume = decimals;
|
||||
|
||||
// Keep backend player volume in sync (best-effort).
|
||||
invoke('player_set_volume', { volume: decimals }).catch(() => {});
|
||||
// If currently in cast mode and a device is selected, propagate volume
|
||||
if (currentMode === 'cast' && currentCastDevice) {
|
||||
invoke('cast_set_volume', { deviceName: currentCastDevice, volume: decimals }).catch(()=>{});
|
||||
@@ -103,6 +108,44 @@ function restoreSavedVolume() {
|
||||
}
|
||||
}
|
||||
|
||||
function stopLocalPlayerStatePolling() {
|
||||
if (localPlayerPollId) {
|
||||
try { clearInterval(localPlayerPollId); } catch (e) {}
|
||||
localPlayerPollId = null;
|
||||
}
|
||||
}
|
||||
|
||||
function startLocalPlayerStatePolling() {
|
||||
stopLocalPlayerStatePolling();
|
||||
// Polling keeps the existing UI in sync with native buffering/reconnect.
|
||||
localPlayerPollId = setInterval(async () => {
|
||||
try {
|
||||
if (!isPlaying || currentMode !== 'local') return;
|
||||
const st = await invoke('player_get_state');
|
||||
if (!st || !statusTextEl || !statusDotEl) return;
|
||||
|
||||
const status = String(st.status || '').toLowerCase();
|
||||
if (status === 'buffering') {
|
||||
statusTextEl.textContent = 'Buffering...';
|
||||
statusDotEl.style.backgroundColor = 'var(--text-muted)';
|
||||
} else if (status === 'playing') {
|
||||
statusTextEl.textContent = 'Playing';
|
||||
statusDotEl.style.backgroundColor = 'var(--success)';
|
||||
} else if (status === 'error') {
|
||||
statusTextEl.textContent = st.error ? `Error: ${st.error}` : 'Error';
|
||||
statusDotEl.style.backgroundColor = 'var(--danger)';
|
||||
} else {
|
||||
// idle/stopped: keep UI consistent with our isPlaying flag
|
||||
}
|
||||
} catch (e) {
|
||||
// Don't spam; just surface a minimal indicator.
|
||||
try {
|
||||
if (statusTextEl) statusTextEl.textContent = 'Error';
|
||||
} catch (_) {}
|
||||
}
|
||||
}, 600);
|
||||
}
|
||||
|
||||
async function loadStations() {
|
||||
try {
|
||||
// stop any existing pollers before reloading stations
|
||||
@@ -896,12 +939,13 @@ async function play() {
|
||||
statusDotEl.style.backgroundColor = 'var(--text-muted)'; // Grey/Yellow while loading
|
||||
|
||||
if (currentMode === 'local') {
|
||||
audio.src = station.url;
|
||||
audio.volume = volumeSlider.value / 100;
|
||||
try {
|
||||
await audio.play();
|
||||
const vol = volumeSlider.value / 100;
|
||||
await invoke('player_set_volume', { volume: vol }).catch(() => {});
|
||||
await invoke('player_play', { url: station.url });
|
||||
isPlaying = true;
|
||||
updateUI();
|
||||
startLocalPlayerStatePolling();
|
||||
} catch (e) {
|
||||
console.error('Playback failed', e);
|
||||
statusTextEl.textContent = 'Error';
|
||||
@@ -926,8 +970,12 @@ async function play() {
|
||||
|
||||
async function stop() {
|
||||
if (currentMode === 'local') {
|
||||
audio.pause();
|
||||
audio.src = '';
|
||||
stopLocalPlayerStatePolling();
|
||||
try {
|
||||
await invoke('player_stop');
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
} else if (currentMode === 'cast' && currentCastDevice) {
|
||||
try {
|
||||
await invoke('cast_stop', { deviceName: currentCastDevice });
|
||||
@@ -981,7 +1029,7 @@ function handleVolumeInput() {
|
||||
const decimals = val / 100;
|
||||
|
||||
if (currentMode === 'local') {
|
||||
audio.volume = decimals;
|
||||
invoke('player_set_volume', { volume: decimals }).catch(() => {});
|
||||
} else if (currentMode === 'cast' && currentCastDevice) {
|
||||
invoke('cast_set_volume', { deviceName: currentCastDevice, volume: decimals });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user