Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Browser tab badge notification

I have been searching how to get a notification badge on the tab of the website page like in the image below, but couldn't find much, or anything that works. I have made a chat site and want people to know if there is a new notification in the channel they are in. But I just need to know how I can get a red badge button on the site favicon or something like that.

Preferably something like how Discord has done:

enter image description here

I have tried this, but doesn't seem to work:

var count = 0;

var title = document.title;

function changeTitle() {
    count++;
    var newTitle = '(' + count + ') ' + title;
    document.title = newTitle;
}

function newUpdate() {
    update = setInterval(changeTitle, 2000);
}
var docBody = document.getElementById('site-body');
docBody.onload = newUpdate;
like image 969
Cohen Avatar asked Jan 14 '21 12:01

Cohen


People also ask

What is browser badge?

Web buttons, badges or stickers are small images in some World Wide Web pages which are typically used to promote programs that were used to create or host the site (for example, MediaWiki sites often have a "Powered by Mediawiki" button on the bottom right corner of the page).

What is meant by notification badges?

Starting with 8.0 (API level 26), notification badges (also known as notification dots) appear on a launcher icon when the associated app has an active notification. Users can long-press on the app icon to reveal the notifications (alongside any app shortcuts), as shown in figure 1.

What are Iphone badges notifications?

Badges are the red little circles or numbers that appear over an app icon on your Home Screen, telling you how many unread notifications you have for that app.

How do I show badge on app icon Android?

Dot-style badge and notification preview option are newly added in Oreo OS. If you want to change badge with number, you can be changed in NOTIFICATION SETTING on the notification panel or Settings > Notifications > App icon badges > Select Show with number.

Where can I display badges with notification counts on surfaces?

For years, desktop and mobile operating systems have supported showing a badge with a notification count on surfaces like the Windows taskbar, macOS dock, and Android or iOS home screen, but this feature has always been limited to native apps. With the latest version of Microsoft Edge, PWAs and pinned sites can now display badges as well.

Can badges be displayed on the taskbar in edge?

Unfortunately, one of the drawbacks of badging in most browsers is that badges can only be shown on the taskbar while the PWA is open. But with the recent changes we’ve made to Microsoft Edge, badges can now be shown on the taskbar at any time.

Can I update a badge with a push event?

However, for privacy reasons, updating a badge via the service worker push event also requires that the site show a toast notification. Users must also opt into receiving notifications from the site. Learn more about how to enable badging on your site.

How to show alert when the user is in another tab?

When user is in another tab, browser has an inbuilt feature of flashing the tabs (having alert). So, changing document title along with an alert will serve your purpose. Note : before showing alert , you need to first check if tab is active.


1 Answers

Tl;Dr: Update the <link> element with a new icon image.

enter image description here

Basically what it does:

  • takes the source of the image from the <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" /> element
  • creates an in-memory Canvas element
  • applies the favicon image
  • draws the shape on top
  • draws the text value on top
  • updates the <link> element href attribute from the final composite of the canvas element imageData

Use like:

const myBadgerOptions = {}; // See: constructor for customization options
const myBadger = new Badger(myBadgerOptions);

// Live update value example:
myBadger.value = 3;

// Remove badge example:
// myBadger.value = 0;

// If needed, get the generated base64 image data: 
// console.log(myBadger.dataURL);

Badger constructor:

/**
 * Add notification badge (pill) to favicon in browser tab
 * @url stackoverflow.com/questions/65719387/
 */
class Badger {
  constructor(options) {
    Object.assign(
      this, {
        backgroundColor: "#f00",
        color: "#fff",
        size: 0.6,      // 0..1 (Scale in respect to the favicon image size)
        position: "ne", // Position inside favicon "n", "e", "s", "w", "ne", "nw", "se", "sw"
        radius: 8,      // Border radius
        src: "",        // Favicon source (dafaults to the <link> icon href)
        onChange() {},
      },
      options
    );
    this.canvas = document.createElement("canvas");
    this.src = this.src || this.faviconEL.getAttribute("href");
    this.ctx = this.canvas.getContext("2d");
  }

  faviconEL = document.querySelector("link[rel$=icon]");

  _drawIcon() {
    this.ctx.clearRect(0, 0, this.faviconSize, this.faviconSize);
    this.ctx.drawImage(this.img, 0, 0, this.faviconSize, this.faviconSize);
  }

  _drawShape() {
    const r = this.radius;
    const xa = this.offset.x;
    const ya = this.offset.y;
    const xb = this.offset.x + this.badgeSize;
    const yb = this.offset.y + this.badgeSize;
    this.ctx.beginPath();
    this.ctx.moveTo(xb - r, ya);
    this.ctx.quadraticCurveTo(xb, ya, xb, ya + r);
    this.ctx.lineTo(xb, yb - r);
    this.ctx.quadraticCurveTo(xb, yb, xb - r, yb);
    this.ctx.lineTo(xa + r, yb);
    this.ctx.quadraticCurveTo(xa, yb, xa, yb - r);
    this.ctx.lineTo(xa, ya + r);
    this.ctx.quadraticCurveTo(xa, ya, xa + r, ya);
    this.ctx.fillStyle = this.backgroundColor;
    this.ctx.fill();
    this.ctx.closePath();
  }

  _drawVal() {
    const margin = (this.badgeSize * 0.18) / 2;
    this.ctx.beginPath();
    this.ctx.textBaseline = "middle";
    this.ctx.textAlign = "center";
    this.ctx.font = `bold ${this.badgeSize * 0.82}px Arial`;
    this.ctx.fillStyle = this.color;
    this.ctx.fillText(this.value, this.badgeSize / 2 + this.offset.x, this.badgeSize / 2 + this.offset.y + margin);
    this.ctx.closePath();
  }

  _drawFavicon() {
    this.faviconEL.setAttribute("href", this.dataURL);
  }

  _draw() {
    this._drawIcon();
    if (this.value) this._drawShape();
    if (this.value) this._drawVal();
    this._drawFavicon();
  }

  _setup() {
    this.faviconSize = this.img.naturalWidth;
    this.badgeSize = this.faviconSize * this.size;
    this.canvas.width = this.faviconSize;
    this.canvas.height = this.faviconSize;
    const sd = this.faviconSize - this.badgeSize;
    const sd2 = sd / 2;
    this.offset = {
      n:  {x: sd2, y: 0 },
      e:  {x: sd, y: sd2},
      s:  {x: sd2, y: sd},
      w:  {x: 0, y: sd2},
      nw: {x: 0, y: 0},
      ne: {x: sd, y: 0},
      sw: {x: 0, y: sd},
      se: {x: sd, y: sd},
    }[this.position];
  }

  // Public functions / methods:

  update() {
    this._value = Math.min(99, parseInt(this._value, 10));
    if (this.img) {
      this._draw();
      if (this.onChange) this.onChange.call(this);
    } else {
      this.img = new Image();
      this.img.addEventListener("load", () => {
        this._setup();
        this._draw();
        if (this.onChange) this.onChange.call(this);
      });
      this.img.src = this.src;
    }
  }

  get dataURL() {
    return this.canvas.toDataURL();
  }

  get value() {
    return this._value;
  }

  set value(val) {
    this._value = val;
    this.update();
  }
}
like image 120
Roko C. Buljan Avatar answered Oct 26 '22 22:10

Roko C. Buljan