Avatar billede Strawberry Seniormester
21. april 2020 - 16:30 Der er 7 kommentarer og
1 løsning

Side der viser hvis der er nye beskeder i min Google Mail og afspiller lyd

Jeg har lavet denne kode som virker fint.

Det kan nok optimeres lidt.

Jeg kunne godt tænke mig at lave en knap, så siden kan tjekke om der er kommet nye beskeder igen, hvis der er kommet nye beskeder.

Man kan reloade siden og trykke på start igen. Kan det lade sig gøre at lave en knap så man ikke behøver reloade siden først?

Kan det også lade sig gøre at tjekke om der er trykket på start, så funktionen ikke kører flere gange samtidig, hvis man klikker på start flere gange?

<?php
$username = 'username???';
$password = 'password???';

$qmode = "";
if (isset($_GET['mode']))
$qmode = $_GET['mode'];

if ($qmode == "update") {

/* connect to gmail */
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
//$username = 'username???';
//$password = 'password???';
/* try to connect */
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());
/* grab emails */
$emails = imap_search($inbox,'ALL');
/* if emails are returned, cycle through each... */
if($emails) {       
        /* begin output var */
        $output = '';       
        /* put the newest emails on top */
        rsort($emails);       

        $email_number = $emails[0];
                $overview = imap_fetch_overview($inbox,$email_number,0);
                $output.= 'on '.$overview[0]->date.'';

        echo $output;
}
imap_close($inbox);
exit;
}
?>

<!DOCTYPE html>
<html>
<body>

<input type=button onclick=enableStart(); value=Start>

<br><br>

<script>
setTimeout("document.title='(...) Home';",1000);
setTimeout("document.title='(0) Home';",3000);
</script>

<embed src="sound.mp3" type="audio/mp3" autostart="true" hidden="true">
        <audio id="myAudio" autoplay controls><source src="sound.mp3" type="audio/mp3"></audio>
</embed>

<script>
var x = document.getElementById("myAudio");

function enableStart() {
  x.autoplay = true;
  setTimeout("data()",1*5000);
  document.getElementById("div1").innerHTML = 'Tjekker om der er kommet nye meddelelser...';
}

function enableAutoplay() {
  x.autoplay = true;
  x.load();

setTimeout("enableAutoplay()",15*1000);

//alert(document.getElementById("div1").innerHTML);

}

function disableAutoplay() {
  x.autoplay = false;
  x.load();
}
 
function checkAutoplay() {
  alert(x.autoplay);
}
</script>

<br><br>

<button onclick="enableAutoplay()" type="button">Enable autoplay</button>
<button onclick="disableAutoplay()" type="button">Disable autoplay</button>
<button onclick="checkAutoplay()" type="button">Check autoplay status</button>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<!-- kan hentes lokalt i stedet for: -->
<!--script src="jquery.min.js"></script-->

<script>
function data() {

$(document).ready(function(){
//  $("button").click(function(){
    $("#div1").load("index.php?mode=update", function(responseTxt, statusTxt, xhr){
      if(statusTxt == "success") {


<?php
// ### read last - start

/* connect to gmail */
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
//$username = 'username???';
//$password = 'password???';
/* try to connect */
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());
/* grab emails */
$emails = imap_search($inbox,'ALL');
/* if emails are returned, cycle through each... */
if($emails) {       
        /* begin output var */
        $output = '';       
        /* put the newest emails on top */
        rsort($emails);       
        /* for every email... */

                $email_number = $emails[0];
                $overview = imap_fetch_overview($inbox,$email_number,0);
                $output.= 'on '.$overview[0]->date.'';

//        echo $output;
}
imap_close($inbox);

// ### read last - end
?>

        var last_message_on_page = "<?= $output; ?>";

        if (responseTxt != last_message_on_page) {

          //alert('Der er kommet nye beskeder... Der vises en besked (information) om dette på siden...');
          document.getElementById("div1").innerHTML = "Der er kommer nye meddelelser...";
          document.title='(1) Der er nye meddelelser...';
          enableAutoplay();
        }
        else {
            setTimeout("data()",30*1000);
        }

        //alert("External content loaded successfully!");
        }
      if(statusTxt == "error") {
        //alert("Error: " + xhr.status + ": " + xhr.statusText);
        }
    });
//  });
});

}
//setTimeout("data()",1*1000);
</script>

<div id="div1"><h2>Let jQuery AJAX Change This Text</h2></div>

<!--
<button>Get External Content</button>

Afspiller kun lyd hvis filen ... eksisterer, kan evt. tilpasses til at læse fra database. Der skal klikkes på siden før der kan afspilles lyd.
-->

</body>
</html>
Avatar billede Strawberry Seniormester
21. april 2020 - 17:02 #2
Forstår du hvad det er jeg spørger om og har du overhovedet kigget på min php-kode?

Det du siger, sker allerede i den kode jeg har, den tjekker hvert 30. sekund...
Avatar billede claes57 Ekspert
21. april 2020 - 17:35 #3
er det ikke lidt hysterisk at tjekke 2 gange pr minut hvis svaret er det samme indtil et evt reload? Du vil jo få samme svar selvom du kun tjekkede en enkelt gang.
og - ikke for noget - men har du fx thunderbird, så sætter den en lille ping i systembakken når der er ny/ulæst post - hvorfor gå over åen efter vand?
Avatar billede Slater Ekspert
21. april 2020 - 19:24 #4
Koden der giver ikke rigtig nogen mening, men den er også meget rodet, så det er svært at forstå hvad der er tiltænkt med den.

F.eks. sætter din data() funktion bare en event handler på når siden loader - men siden vil allerede være loadet når den køres flere gange, så det gør ikke noget. Der er en masse setTimeouts, hvoraf nogle af udkommenterede, men de har ikke rigtig noget formål på grund af dette.

Jeg må indrømme jeg heller ikke helt forstår spørgsmålene. Skal det køre af sig selv? Vil du have den skal tjekke manuelt én gang når man trykker start? Kan du evt. forklare lidt bedre?
Avatar billede Strawberry Seniormester
21. april 2020 - 19:48 #5
Ja det kører automatisk når man klikker på knappen start. Filen skal bare hedde index.php

Således:

<input type=button onclick=enableStart(); value=Start>

Jeg kan også bare lave en stop knap således:

<input type=button onclick="location=location.href;" value=Stop>

Det er meningen den skal afspille lyd, hvis der er nye beskeder og hvis der blive ved med at blive afspillet lyd hvert 15. sekund indtil man stopper den.

Derfor denne timeout:

setTimeout("enableAutoplay()",15*1000);

Disse 2 timeout bliver kun brugt til at ændre side title:

setTimeout("document.title='(...) Home';",1000);
setTimeout("document.title='(0) Home';",3000);

Hvis der ikke bliver fundet nye meddelelser, så køres funktionen data igen:

setTimeout("data()",30*1000);

Det er bare for at teste om det virker at jeg har sat den til 30. sekunder

Det er nok mere passende med 5 minutter:

setTimeout("data()",300*1000);

Jeg ved godt det er meget rodet, det er også derfor jeg spørger om hjælp.

Det jeg spurgte om var hvordan jeg undgår at funktionen data() starter flere gange, hvis funktionen allerede er startet og man klikker på knappen "start" (som starter funktionen data() )

Det ser ud til det kan gøres, således:

<div id="div_status">Status: Stoppet</div>

function enableStart() {
  x.autoplay = true;
if (document.getElementById("div_status").innerHTML == 'Status: Stoppet') {
  document.getElementById("div_status").innerHTML = 'Status: Startet';
  setTimeout("data()",1*5000);
}
  document.getElementById("div1").innerHTML = 'Tjekker om der er kommet nye meddelelser...';
}

Er der en pænere og bedre måde?
Avatar billede Strawberry Seniormester
21. april 2020 - 20:18 #6
Det kan nok optimeres lidt således:

$count = imap_num_msg($inbox);

            $email_number = $count;

Og så fjerne disse 2 linjer:

$emails = imap_search($inbox,'ALL');

    rsort($emails);
Avatar billede Slater Ekspert
22. april 2020 - 07:08 #7
Tak, det var en fin forklaring.

Som jeg forstår det er du bare ude på at kunne starte og stoppe et interval med et par knapper. Den nemmeste måde at gøre det er at bruge pointeren til selve timeren. F.eks. sådan:
http://snip.kilolima.dk/#/RTVluiK

Er det misforstået? Er der også problemer med PHP'en?
Avatar billede Strawberry Seniormester
23. april 2020 - 10:11 #8
Det er rigtigt forstået. Det var lige det jeg havde brug for.

Der er ikke nogen problemer med php-koden.

Der er ændret lidt så det ser lidt pænere ud:

<script>
function read_last_message() {
<?php
// ### read last - start

$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
//$username = 'username???';
//$password = 'password???';
/* try to connect */
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());

$count = imap_num_msg($inbox);

        $output = '';       

                $email_number = $count;

                $overview = imap_fetch_overview($inbox,$email_number,0);
                $output.= 'on '.$overview[0]->date.'';

imap_close($inbox);

// ### read last - end
?>
return '<?= $output; ?>';
}
</script>

Og i funktionen data er der ikke længere noget php-kode blandet sammen med klientside script.

Så denne linje er ændret i funktionen data:

var last_message_on_page = read_last_message();
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester