Search code examples
phpjqueryajaxaudioopencart-3

Play audio only once on new email notification


I have tried following code to play audio alert on new unread email notification.

New email number is getting updated but audio is playing in loop which is not expected (it should play once only). secondly, audio replays on page refresh or moving on other page.

I want to show notification update + audio just once (irrespective of staying on same page or moving on other page...) But audio should played once again if new email arrived in between and unread email number is increased (this new unread email number is getting updated successfully).

Header HTML and php Part :

<?php
$this->session->data['new_email_count'] = $this->model_extension_module_message_system->getTotalUnreadMessagesAjax();
 ?>

<li>
  <a href="{{ link_message_system }}" >
        <span class="label label-danger pull-left mt-10 unreadNotification" id="alert_messages"></span> <i class="fa fa-envelope fa-lg text-danger"></i>
  </a>          
 <span id="audio_span"></span>
</li>

JS in header:

<script>
function getNotification() {
 $.ajax({
    type: 'post',
    url: 'index.php?route=extension/module/message_system/GetNewEmailNotification&user_token={{ user_token }}',
    dataType: 'json',       
    success: function(data) {
        $(".unreadNotification").text(data.count);

        if(data.alerterror == 1) {
                playAudio();                
        }
    }
});

}


$(document).ready(function(){
  setInterval(getNotification, 5000);
});


 function playAudio() {
  $("#audio_span").append('<audio nocontrols autoplay hidden="" id="message_audio_alert" src="../image/{{ audio_url }}" type ="audio/mp3">your browser does not support Html5</audio>');

 }
</script>

controller php : (from where ajax call success functions gets data)

<?php
public function GetNewEmailNotification() {
    $this->load->model('extension/module/message_system');
    $this->language->load('extension/module/message_system');
    
    $count= $this->model_extension_module_message_system->getTotalUnreadMessagesAjax();
    
    if((isset($this->session->data['new_email_count'])) && ($this->session->data['new_email_count'] != $count)){
        $alerterror = '1';
    }else{
        $alerterror = '0';
    }
    
    $setting_data['alerterror'] = $alerterror;
    $setting_data['count'] = $count;
            
    $this->response->addHeader('Content-Type: application/json');
    $this->response->setOutput(json_encode($setting_data));
 }

model php function :

<?php
public function getTotalUnreadMessagesAjax() {  
    $sql ="SELECT COUNT(*) AS total FROM " . DB_PREFIX . "messages WHERE message_id > 0 AND read_status='0' AND sender='customer'";     
    $query = $this->db->query($sql);
    return $query->row['total'];
 }      
    

Solution

  • You are appending audio tag every single time you enable playAudio function.

    I can suggest you two solutions:

    1. you could remove this tag after the music is stopped, then it wouldn't be looped
    setTimeout(function(){
      if ($('#message_audio_alert').length > 0) {
        $('#message_audio_alert').remove();
      }
    }, 5000)
    
    1. you could remove autoplay parameter from audio tag, load audio tag once at the beginning of the HTML file, then just enable and disable it instead of loading the whole resource every single time the request appear
    <span id="audio_span">
        <audio nocontrols hidden="" id="message_audio_alert" src="../image/{{ audio_url }}" type ="audio/mp3">your browser does not support Html5</audio>
    </span>
    
    function playAudio() {
        let messageAudioAlert = $("#message_audio_alert")[0];
        messageAudioAlert.play();
    
        setTimeout(function () {
            messageAudioAlert.pause();
            messageAudioAlert.currentTime = 0;
        }, 5000);
    }