let isPlaying = false; let currentSong = ''; let isFirstLoad = true; const audio = new Audio('https://azura.servercast.com.br/listen/piuara_fm/radio.mp3' + '?nocache=' + new Date().getTime()); const playButton = document.getElementById('playButton'); const volumeSlider = document.getElementById('volumeSlider'); const playIcon = document.getElementById('playIcon'); const volumeIcon = document.getElementById('volumeIcon'); const artistName = document.getElementById('artist'); const songTitle = document.getElementById('song'); playButton.addEventListener('click', () => { if (isPlaying) { audio.pause(); playIcon.className = 'bi bi-play-fill'; } else { audio.src = 'https://azura.servercast.com.br/listen/piuara_fm/radio.mp3' + '?nocache=' + new Date().getTime(); audio.play(); playIcon.className = 'bi bi-stop-fill'; } isPlaying = !isPlaying; }); volumeSlider.addEventListener('input', (e) => { const volume = e.target.value / 100; audio.volume = volume; if (volume === 0) { volumeIcon.className = 'bi bi-volume-mute-fill'; } else if (volume < 0.5) { volumeIcon.className='bi bi-volume-down-fill' ; } else { volumeIcon.className='bi bi-volume-up-fill' ; } }); function updateMetadata() { $.ajax({ url: 'https://azura.servercast.com.br/api/nowplaying/103' , dataType: 'json' , success: function(data) { if (data && data.now_playing && data.now_playing.song) { const newArtist=data.now_playing.song.artist; const newTitle=data.now_playing.song.title; if (currentSong !==`${newArtist} - ${newTitle}` || isFirstLoad) { currentSong=`${newArtist} - ${newTitle}`; artistName.textContent=newArtist; songTitle.textContent=newTitle; isFirstLoad=false; } } else { songTitle.textContent='Transmissão Online' ; artistName.textContent=data.station.name || 'Rádio Desconhecida' ; } }, error: function(xhr, status, error) { console.error('Error fetching metadata:', error); songTitle.textContent='Não foi possível obter os dados' ; artistName.textContent='Tente novamente' ; } }); } updateMetadata(); setInterval(updateMetadata, 25000); // Widget Tempo const CONFIG={ cityId: '3396016' , // City ID from OpenWeatherMap or city name apiKey: 'b802c9a05222d515253e3fafd06eeeda' , // Your OpenWeatherMap API key units: 'metric' , // 'metric' for Celsius, 'imperial' for Fahrenheit lang: 'pt' , // Language for weather descriptions updateInterval: 30, // Update interval in minutes useMockData: false, // Set to true to use mock data instead of API useV3API: true // Use OpenWeatherMap API v3.0 }; // Weather icons mapping const weatherIcons={ 'clear sky' : '☀️' , 'few clouds' : '🌤️' , 'scattered clouds' : '⛅' , 'broken clouds' : '☁️' , 'shower rain' : '🌦️' , 'rain' : '🌧️' , 'thunderstorm' : '⛈️' , 'snow' : '🌨️' , 'mist' : '🌫️' , 'overcast clouds' : '☁️' , 'moderate rain' : '🌧️' , 'light rain' : '🌦️' , 'heavy intensity rain' : '🌧️' , 'default' : '🌥️' }; function getWeatherIcon(condition) { const lowerCondition=condition.toLowerCase(); return weatherIcons[lowerCondition] || weatherIcons['default']; } function displayWeather(data) { document.getElementById('current-city').textContent=data.city?.name || 'São Paulo' ; // Clima atual const current=data.list[0]; const currentTemp=Math.round(current.main.temp); const currentWeather=current.weather[0].description; document.getElementById('current-temp').textContent=`${currentTemp}°`; document.getElementById('current-icon').textContent=getWeatherIcon(currentWeather); // Previsão de 3 dias const days=['day1', 'day2' , 'day3' ]; const dayNames=['Dom', 'Seg' , 'Ter' , 'Qua' , 'Qui' , 'Sex' , 'Sáb' ]; days.forEach((day, index)=> { const forecastDay = new Date(); forecastDay.setHours(0, 0, 0, 0); forecastDay.setDate(forecastDay.getDate() + (index + 1)); // Coleta todas as previsões do dia específico const dayDataList = data.list.filter(item => { const date = new Date(item.dt * 1000); return ( date.getDate() === forecastDay.getDate() && date.getMonth() === forecastDay.getMonth() && date.getFullYear() === forecastDay.getFullYear() ); }); if (dayDataList.length > 0) { // Determina mínima e máxima reais do dia const temps = dayDataList.map(item => ({ min: item.main.temp_min, max: item.main.temp_max })); const minTemp = Math.min(...temps.map(t => t.min)); const maxTemp = Math.max(...temps.map(t => t.max)); // Escolhe um horário representativo (meio-dia ou central) const midDayData = dayDataList.find(item => new Date(item.dt * 1000).getHours() === 12) || dayDataList[Math.floor(dayDataList.length / 2)]; const date = new Date(midDayData.dt * 1000); const dayName = dayNames[date.getDay()]; // Atualiza HTML document.getElementById(`${day}-date`).textContent = dayName; document.getElementById(`${day}-icon`).textContent = getWeatherIcon(midDayData.weather[0].description); document.getElementById(`${day}-high`).textContent = `${Math.round(maxTemp)}°`; document.getElementById(`${day}-low`).textContent = `${Math.round(minTemp)}°`; } }); } // Use CONFIG values instead of localStorage for defaults let cityId = CONFIG.cityId; let apiKey = CONFIG.apiKey; // Settings modal functionality const settingsBtn = document.getElementById('settings-btn'); const settingsModal = document.getElementById('settings-modal'); const cityInput = document.getElementById('city-input'); const apiInput = document.getElementById('api-input'); const saveBtn = document.getElementById('save-settings'); const cancelBtn = document.getElementById('cancel-settings'); settingsBtn.addEventListener('click', () => { cityInput.value = cityId; apiInput.value = apiKey; settingsModal.classList.add('active'); }); cancelBtn.addEventListener('click', () => { settingsModal.classList.remove('active'); }); saveBtn.addEventListener('click', () => { cityId = cityInput.value.trim() || CONFIG.cityId; apiKey = apiInput.value.trim() || CONFIG.apiKey; // Save to localStorage for persistence localStorage.setItem('weatherCityId', cityId); localStorage.setItem('weatherApiKey', apiKey); settingsModal.classList.remove('active'); fetchWeather(); }); // Close modal on outside click settingsModal.addEventListener('click', (e) => { if (e.target === settingsModal) { settingsModal.classList.remove('active'); } }); async function fetchWeather() { if (CONFIG.useMockData) { loadMockData(); return; } try { let url; if (isNaN(cityId)) { url = `https://api.openweathermap.org/data/2.5/forecast?q=${encodeURIComponent(cityId)}&appid=${apiKey}&units=${CONFIG.units}&lang=${CONFIG.lang}`; } else { url = `https://api.openweathermap.org/data/2.5/forecast?id=${cityId}&appid=${apiKey}&units=${CONFIG.units}&lang=${CONFIG.lang}`; } const response = await fetch(url); if (response.status === 401) { console.error('Erro de autenticação. Verifique sua chave API.'); loadMockData(); return; } else if (response.status === 404) { console.error('Cidade não encontrada.'); loadMockData(); return; } else if (response.ok) { const data = await response.json(); displayWeather(data); } else { console.error('API Error:', response.status); loadMockData(); } } catch (error) { console.error('Erro ao buscar dados:', error); loadMockData(); } } function loadMockData() { const mockData = { city: { name: 'São Paulo' }, list: [ { main: { temp: 23, temp_min: 20, temp_max: 25 }, weather: [{ description: 'Limpo' }] }, { main: { temp_min: 18, temp_max: 26 }, weather: [{ description: 'Parcialmente nublado' }] }, { main: { temp_min: 20, temp_max: 27 }, weather: [{ description: 'Chuva leve' }] }, { main: { temp_min: 19, temp_max: 25 }, weather: [{ description: 'Nublado' }] } ] }; displayWeather(mockData); } // Load from localStorage if available, otherwise use CONFIG cityId = localStorage.getItem('weatherCityId') || CONFIG.cityId; apiKey = localStorage.getItem('weatherApiKey') || CONFIG.apiKey; // Auto-update based on CONFIG.updateInterval fetchWeather(); setInterval(fetchWeather, CONFIG.updateInterval * 60 * 1000);