Asked  9 Months ago    Answers:  5   Viewed   61 times

I noticed Facebook started using the HTML5 notification for desktop and I thought I would start dabbling in it for fun for my blog. My idea is pretty simple: new blog comes out, apache cronjob runs every X minutes and calls a file, does some PHP wizardry and out goes the notification.

I have looked online and found examples using node.js and angular, but I'm not comfortable using either of those so I'd rather stick with PHP.

Here is my process: The user goes to my blog and will click a button to allow notifications. For brevity, the below code sends the users a notification when they click the "notify" button. This works perfectly, and in theory should subscribe them to any future notifications.

if ('Notification' in window) {

function notifyUser() {
    var title = 'example title';
    var options = {
        body: 'example body',
        icon: 'example icon'
    };

    if (Notification.permission === "granted") {
        var notification = new Notification(title, options);
    } else if (Notification.permission !== 'denied') {
        Notification.requestPermission(function (permission) {
            if (permission === "granted") {
                var notification = new Notification(title, options);
            }
        });
    }

}

$('#notify').click(function() {
    notifyUser();
    return false;
});

} else {
    //not happening
}

You can see the fiddle of the above.

Access to the user is granted and now I should be able to send them notifications whenever I want. Awesome! I then write up a blog entry and it has the ID of XYZ. My cronjob goes and calls the following PHP script, using the above node.js example as a template.

(In this example I am just calling the script manually from my phone and watching my desktop screen. Since my desktop is "subscribed" to the same domain, I think the following would/should work.)

$num = $_GET['num'];

$db = mysql_connect(DB_HOST, DB_USER, DB_PASS);
if($db) {
    mysql_select_db('mydb', $db);
    $select = "SELECT alert FROM blog WHERE id = ".$num." && alert = 0 LIMIT 1";
    $results = mysql_query($select) or die(mysql_error());
    $output = '';
    while($row = mysql_fetch_object($results)) { 

        $output .= "<script>

        var title = 'new blog!';
        var options = {
            body: 'come read my new blog!',
            icon: 'same icon as before or maybe a new one!'
        };

        var notification = new Notification(title, options);

        </script>";

      $update = "UPDATE blog SET alert = 1 WHERE id = ".$num." && alert = 0 LIMIT 1";
      mysql_query($update) or die(mysql_error());

    }

    echo $output;

}

I then check the database and blog entry XYZ's "alert" is now set to "1", yet my desktop browser never got notified. Since my browser is subscribed to the same URL that is pushing out the notification, I would imagine I'd get a message.

Either I'm doing something wrong (perhaps PHP isn't the right language for this?), or I'm misunderstanding the spec. Could somebody help point me in the right direction? I think I'm missing something.

Thanks a lot.

Update 1

According to the comments, if I just call a script with this in it:

 var title = 'new blog!';
 var options = {
    body: 'come read my new blog!',
    icon: 'same icon as before or maybe a new one!'
 };

  var notification = new Notification(title, options);

It should hit all devices that are subscribed to my notifications. I tried this on my phone but my desktop still didn't get a notification. I still think I'm missing something as my notifications seem stuck to one device and can only be called on page-load or on click as opposed to Facebook which sends you notifications even if the page isn't open in your browser.

 Answers

84

Your problem is the lack of AJAX to connect Javascript and PHP. The way your PHP script works is by manually running the script, so only the device hitting that script will see the notification. There is nothing that actually sends that info to your other device right now.

To better explain the problem, your desktop may have allowed access to the notifications, but it doesn't automatically pull in those notifications. The code you have provided will need to use AJAX to hit the script URL, instead of using it as a cron job.

First off, you need to start a repeating request to the PHP script to see if there has been any updated notification. If there is a new notification, then you need to create a new notification object using the returned response.

Second, you need to alter the PHP script to output a JSON string rather instead of the notification script.

JSON output example:

{
  {
    title: 'new blog!',
    options: {
      body: 'come read my new blog!',
      icon: 'same icon as before or maybe a new one!'
    }
  },
  {
    title: 'another blog item!',
    options: {
      body: 'come read my second blog!',
      icon: 'hooray for icons!'
    }
  }
}

Your notifyUsers() should take title and option as arguments instead of hardcoding them:

function notifyUser(title, options) { ... }

Using jQuery, get the PHP response and create the notification:

function checkNotifications(){
  $.get( "/path/to/script.php", function( data ) {
    // data is the returned response, let's parse the JSON string
    json = JSON.parse(data);

    // check if any items were returned
    if(!$.isEmptyObject(json)){
      // send each item to the notify function
      for(var i in json){
        notifyUser(json[i].title, json[i].options);
      }
    }
  });

  setTimeout(checkNotifications, 60000); // call once per minute
}

Now, you just need to kickstart the AJAX polling, so add this to your webpage:

$(document).ready(checkNotifications);

That's pretty much it! You were just missing the part when your desktop needed to pull in the notifications. Heads up though, this isn't tested and you may need to tweek something.

Wednesday, March 31, 2021
 
nighter
answered 9 Months ago
85

I made a JSFiddle. I have removed loop autoplay from the video tags.

$("#myCarousel").carousel({
  interval: 4500
});

$("#myCarousel").on('slid.bs.carousel', function () {
   var vids = $(this).find(".active video");
   if(vids.length > 0){
      vids[0].pause();
      vids[0].currentTime = 0;
      vids[0].play();
   }
})
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>

<div id="myCarousel" class="carousel slide carousel-fade" data-ride="carousel">
<div class="carousel-inner">
    <div class="carousel-item active">
        <img src="">
    </div>
    <div class="carousel-item">
        <video id="myVideo" muted><source src="https://www.w3schools.com/html/mov_bbb.mp4"></video>
    </div>
    <div class="carousel-item">
        <video id="myVideo2" muted><source src="https://www.w3schools.com/html/mov_bbb.mp4"></video>
    </div>
</div>
</div>
Saturday, May 29, 2021
 
muaddhib
answered 7 Months ago
77

Try the following:

navigator.serviceWorker.register('sw.js');
Notification.requestPermission(function(result) {
  if (result === 'granted') {
    navigator.serviceWorker.ready.then(function(registration) {
      registration.showNotification('Notification with ServiceWorker');
    });
  }
});

That should work on Android both in Chrome and in Firefox (and on iOS in Safari, too).

(The sw.js file can just be a zero-byte file.)

One caveat is that you must run it from a secure origin (an https URL, not an http URL).

See https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/showNotification.

Monday, June 28, 2021
 
Tak
answered 6 Months ago
Tak
46

Here's one way using getImageData to manipulate the hue of each image pixel:

  • Use getImageData to fetch the RGBA color data of each pixel

  • Convert the RGBA color to HSL color. The H in HSL means Hue which is what we normally think of as "color".

  • If the Hue of an original pixel is red-ish (Hue<30 or Hue>300) then shift the hue by the amount specified in your range control. If you want to shift from red to blue, then your slider should shift the color (Hue) from 0 to -.33.

Note: getImageData requires that the image originate on the same domain as the webpage or else you will get a cross-domain security error.

Here's example code and a Demo:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var imgData,data,originalData;

$myslider=$('#myslider');
$myslider.attr({min:0,max:33}).val(0);
$myslider.on('input change',function(){
  var value=parseInt($(this).val());
  HueShift(30,300,-value/100);
});

var img=new Image();
img.crossOrigin='anonymous';
img.onload=start;
img.src="http://icons.iconarchive.com/icons/iconshow/transport/256/Sportscar-car-icon.png";
function start(){
  cw=canvas.width=img.width;
  ch=canvas.height=img.height;
  ctx.drawImage(img,0,0);

  imgData=ctx.getImageData(0,0,cw,ch);
  data=imgData.data;
  imgData1=ctx.getImageData(0,0,cw,ch);
  originalData=imgData1.data;

}



function HueShift(hue1,hue2,shift){

  for(var i=0;i<data.length;i+=4){
    red=originalData[i+0];
    green=originalData[i+1];
    blue=originalData[i+2];
    alpha=originalData[i+3];

    // skip transparent/semiTransparent pixels
    if(alpha<230){continue;}

    var hsl=rgbToHsl(red,green,blue);
    var hue=hsl.h*360;

    // change redish pixels to the new color
    if(hue<30 || hue>300){


      var newRgb=hslToRgb(hsl.h+shift,hsl.s,hsl.l);
      data[i+0]=newRgb.r;
      data[i+1]=newRgb.g;
      data[i+2]=newRgb.b;
      data[i+3]=255;
    }
  }    
  ctx.putImageData(imgData,0,0);
}






////////////////////////
// Helper functions
//

function rgbToHsl(r, g, b){
  r /= 255, g /= 255, b /= 255;
  var max = Math.max(r, g, b), min = Math.min(r, g, b);
  var h, s, l = (max + min) / 2;
  if(max == min){
    h = s = 0; // achromatic
  }else{
    var d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
    switch(max){
      case r: h = (g - b) / d + (g < b ? 6 : 0); break;
      case g: h = (b - r) / d + 2; break;
      case b: h = (r - g) / d + 4; break;
    }
    h /= 6;
  }
  return({ h:h, s:s, l:l });
}

function hslToRgb(h, s, l){
  var r, g, b;
  if(s == 0){
    r = g = b = l; // achromatic
  }else{
    function hue2rgb(p, q, t){
      if(t < 0) t += 1;
      if(t > 1) t -= 1;
      if(t < 1/6) return p + (q - p) * 6 * t;
      if(t < 1/2) return q;
      if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
      return p;
    }
    var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
    var p = 2 * l - q;
    r = hue2rgb(p, q, h + 1/3);
    g = hue2rgb(p, q, h);
    b = hue2rgb(p, q, h - 1/3);
  }
  return({
    r:Math.round(r * 255),
    g:Math.round(g * 255),
    b:Math.round(b * 255),
  });
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Change the slider to change the car color</h4>
<input id=myslider type=range min=0 max=100 value=0><br>
<canvas id="canvas" width=300 height=300></canvas>
Tuesday, October 5, 2021
 
LDropl
answered 2 Months ago
34

If you insist on using PRIORITY_MAX, you can disable the Heads-Up notification using the following code starting with API 21:

notification.headsUpContentView = new RemoteViews(Parcel.obtain());
Sunday, November 14, 2021
 
Ramazan Polat
answered 2 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share