PageSourceSearch

https://cdn.navidiku.rs/assets/afrodita/default/index/js/radio-player.js?v=2026.06.16.b

js navidiku.rs collected 2026-10-02 05:00:21 UTC 7,249 bytes, 253 lines download raw bytes

1// Radio Player functionality
2let currentStation = null;
3let currentStationIndex = 0;
4let stations = [];
5let audioElement = null;
6let isPlaying = false;
7
8function initializeRadioPlayer() {
9    const radioCards = document.querySelectorAll('.radio-card');
10    const stickyPlayer = document.getElementById('radio-player-sticky');
11    const playPauseBtn = document.getElementById('player-play-pause-btn');
12    const prevBtn = document.getElementById('player-prev-btn');
13    const nextBtn = document.getElementById('player-next-btn');
14    const closeBtn = document.getElementById('player-close-btn');
15    const volumeBtn = document.getElementById('player-volume-btn');
16    const volumeSlider = document.getElementById('player-volume-slider');
17
18    if (!stickyPlayer) return;
19
20    // Initialize audio element
21    audioElement = new Audio();
22    audioElement.volume = 0.8;
23
24    // Collect all stations data
25    radioCards.forEach((card, index) => {
26        stations.push({
27            id: card.dataset.stationId,
28            name: card.querySelector('.radio-name')?.textContent || 'Radio Station',
29            description: card.querySelector('.radio-description')?.textContent || '',
30            song: card.querySelector('.now-playing-song')?.textContent || 'Live Stream',
31            logo: card.querySelector('.radio-logo img')?.src || 'assets/images/radio-placeholder.png',
32            streamUrl: card.dataset.streamUrl || '#',
33            element: card
34        });
35    });
36
37    // Radio card click handlers
38    radioCards.forEach((card, index) => {
39        const playBtn = card.querySelector('.radio-play-btn');
40
41        if (playBtn) {
42            playBtn.addEventListener('click', (e) => {
43                e.stopPropagation();
44                playStation(index);
45            });
46        }
47
48        card.addEventListener('click', () => {
49            playStation(index);
50        });
51    });
52
53    // Play/Pause button
54    if (playPauseBtn) {
55        playPauseBtn.addEventListener('click', togglePlayPause);
56    }
57
58    // Previous button
59    if (prevBtn) {
60        prevBtn.addEventListener('click', playPreviousStation);
61    }
62
63    // Next button
64    if (nextBtn) {
65        nextBtn.addEventListener('click', playNextStation);
66    }
67
68    // Close button
69    if (closeBtn) {
70        closeBtn.addEventListener('click', closePlayer);
71    }
72
73    // Volume button (mute/unmute)
74    if (volumeBtn) {
75        volumeBtn.addEventListener('click', toggleMute);
76    }
77
78    // Volume slider
79    if (volumeSlider) {
80        volumeSlider.addEventListener('input', (e) => {
81            const volume = e.target.value / 100;
82            setVolume(volume);
83        });
84    }
85
86    // Audio event listeners
87    audioElement.addEventListener('play', () => {
88        updatePlayingState(true);
89    });
90
91    audioElement.addEventListener('pause', () => {
92        updatePlayingState(false);
93    });
94
95    audioElement.addEventListener('error', () => {
96        console.error('Error loading radio stream');
97        alert('Greška pri učitavanju radio stanice. Pokušajte ponovo.');
98    });
99}
100
101function playStation(index) {
102    currentStationIndex = index;
103    currentStation = stations[index];
104
105    audioElement.src = currentStation.streamUrl;
106    audioElement.play();
107
108
109    // Update sticky player info
110    updatePlayerInfo();
111
112    // Show sticky player
113    const stickyPlayer = document.getElementById('radio-player-sticky');
114    if (stickyPlayer) {
115        stickyPlayer.classList.add('active');
116        stickyPlayer.style.display = 'block';
117    }
118
119    // Update all radio cards
120    updateRadioCards();
121
122    // Play audio (in real implementation, this would play the actual stream)
123    // For mockup, we'll just simulate playing
124    isPlaying = true;
125    updatePlayingState(true);
126
127    // Simulate loading
128    showLoading();
129    setTimeout(() => {
130        hideLoading();
131    }, 1000);
132}
133
134function togglePlayPause() {
135    if (isPlaying) {
136        pause();
137    } else {
138        play();
139    }
140}
141
142function play() {
143    isPlaying = true;
144    updatePlayingState(true);
145}
146
147function pause() {
148    isPlaying = false;
149    updatePlayingState(false);
150}
151
152function playPreviousStation() {
153    currentStationIndex = (currentStationIndex - 1 + stations.length) % stations.length;
154    playStation(currentStationIndex);
155}
156
157function playNextStation() {
158    currentStationIndex = (currentStationIndex + 1) % stations.length;
159    playStation(currentStationIndex);
160}
161
162function closePlayer() {
163    pause();
164    const stickyPlayer = document.getElementById('radio-player-sticky');
165    if (stickyPlayer) {
166        stickyPlayer.classList.remove('active');
167        setTimeout(() => {
168            stickyPlayer.style.display = 'none';
169        }, 300);
170    }
171    updateRadioCards();
172}
173
174function toggleMute() {
175    const volumeBtn = document.getElementById('player-volume-btn');
176    const volumeSlider = document.getElementById('player-volume-slider');
177
178    if (audioElement.volume > 0) {
179        audioElement.dataset.previousVolume = audioElement.volume;
180        setVolume(0);
181        volumeSlider.value = 0;
182        volumeBtn.classList.add('muted');
183    } else {
184        const previousVolume = parseFloat(audioElement.dataset.previousVolume) || 0.8;
185        setVolume(previousVolume);
186        volumeSlider.value = previousVolume * 100;
187        volumeBtn.classList.remove('muted');
188    }
189}
190
191function setVolume(volume) {
192    if (audioElement) {
193        audioElement.volume = volume;
194    }
195}
196
197function updatePlayerInfo() {
198    if (!currentStation) return;
199
200    const stationName = document.getElementById('player-station-name');
201    const songName = document.getElementById('player-song-name');
202    const logo = document.getElementById('player-logo');
203
204    if (stationName) stationName.textContent = currentStation.name;
205    if (songName) songName.textContent = currentStation.song;
206    if (logo) logo.src = currentStation.logo;
207}
208
209function updatePlayingState(playing) {
210    isPlaying = playing;
211    const playPauseBtn = document.getElementById('player-play-pause-btn');
212
213    if (playPauseBtn) {
214        if (playing) {
215            playPauseBtn.classList.add('playing');
216        } else {
217            playPauseBtn.classList.remove('playing');
218        }
219    }
220
221    updateRadioCards();
222}
223
224function updateRadioCards() {
225    stations.forEach((station, index) => {
226        const card = station.element;
227        const playBtn = card.querySelector('.radio-play-btn');
228
229        if (index === currentStationIndex && isPlaying) {
230            card.classList.add('playing');
231            if (playBtn) {
232                playBtn.querySelector('.play-icon').style.display = 'none';
233                playBtn.querySelector('.pause-icon').style.display = 'block';
234            }
235        } else {
236            card.classList.remove('playing');
237            if (playBtn) {
238                playBtn.querySelector('.play-icon').style.display = 'block';
239                playBtn.querySelector('.pause-icon').style.display = 'none';
240            }
241        }
242    });
243}
244
245function showLoading() {
246    const loading = document.getElementById('player-loading');
247    if (loading) loading.style.display = 'flex';
248}
249
250function hideLoading() {
251    const loading = document.getElementById('player-loading');
252    if (loading) loading.style.display = 'none';
253}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.