function parseI18Json(el){
const str=el?.dataset.i18n
try {
return JSON.parse(str||'{}')
} catch (e){
console.error(e)
return {}}
}
function initializeAlxAudio(el){
const i18n=parseI18Json(document.querySelector('.alx-audio [data-i18n]'))
let audio=el.querySelector('audio');
if(!audio){
audio=document.createElement('audio');
audio.preload='none';
const preScript=el.querySelector('.pre-script')
audio.src=preScript?.href
el.prepend(audio)
}
audio.controls=false;
if(!audio.src){
console.warn("No audio src on", el);
return;
}
let controls=el.querySelector('.controls');
if(controls){
controls.innerHTML='';
}else{
controls=document.createElement('div');
controls.className='controls';
}
const btnPlay=document.createElement('button');
btnPlay.type='button';
btnPlay.innerHTML=`<span role="presentation">▶︎</span><span class="caption">${i18n.play}</span>`;
btnPlay.dataset.action='play';
btnPlay.addEventListener('click', ()=> {
if(el.dataset.status==='idle'){
el.dataset.status='loading';
}
audio.play()
});
controls.appendChild(btnPlay);
const btnPause=document.createElement('button');
btnPause.type='button';
btnPause.innerHTML=`<span role="presentation">⏸︎</span><span class="caption">${i18n.pause}</span>`;
btnPause.dataset.action='pause';
btnPause.addEventListener('click', ()=> audio.pause());
controls.appendChild(btnPause);
const progress=document.createElement('progress');
progress.value=0;
progress.max=100;
controls.appendChild(progress);
const position=document.createElement('span');
position.classList.add('position');
position.innerText='-0:00';
controls.appendChild(position);
el.append(controls);
audio.addEventListener('playing', ()=> {
el.dataset.status='playing';
if(!positionUpdateInterval){
positionUpdateInterval=setInterval(updateProgress, 500);
}});
audio.addEventListener('pause', ()=> {
el.dataset.status='paused';
if(positionUpdateInterval){
clearInterval(positionUpdateInterval);
positionUpdateInterval=null;
}});
audio.addEventListener('durationchange', ()=> {
progress.max=audio.duration;
});
progress.addEventListener('click', e=> {
const rect=e.target.getBoundingClientRect();
const pct=(e.clientX - rect.left) / rect.width;
const targetTime=pct * audio.duration;
audio.currentTime=targetTime;
updateProgress()
});
let positionUpdateInterval;
function updateProgress(){
progress.value=audio.currentTime;
position.innerText='-' + formatTime(audio.duration - audio.currentTime);
}
function formatTime(seconds){
const minutes=Math.floor(seconds / 60);
seconds -=minutes * 60;
const secondsPadded=(Math.floor(seconds) + '').padStart(2, '0');
return `${minutes}:${secondsPadded}`;
}
el.dataset.status='idle';
}
document.querySelectorAll('.alx-audio').forEach(el=> initializeAlxAudio(el));
document.addEventListener('DOMContentLoaded', function (){
const stars=document.querySelectorAll('.custom-rating-stars i');
const input=document.querySelector('#rating');
let selectedRating=0;
function updateStars(hoverValue=selectedRating){
stars.forEach(star=> {
const value=parseInt(star.dataset.value);
const shining=value <=hoverValue;
star.classList.toggle('fas', shining);
star.classList.toggle('far', !shining);
});
}
stars.forEach(star=> {
star.addEventListener('mouseover', ()=> {
updateStars(parseInt(star.dataset.value));
});
star.addEventListener('mouseout', ()=> {
updateStars();
});
});
stars.forEach(star=> {
star.addEventListener('click', ()=> {
selectedRating=parseInt(star.dataset.value);
input.value=selectedRating;
updateStars();
});
});
updateStars();
});