npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

electron-custom-notifications

v8.0.5

Published

Cross-platform notifications using Electron's BrowserWindow

Downloads

108

Readme

electron-custom-notifications (proof of concept)

Display customized HTML/CSS notifications in a cross-platform way. Instead of relying on Windows, Mac or Linux APIs to show notifications, this uses an extra Electron window to display them, giving the developer the freedom to style the notifications as they choose to.

Full Usage

Please note that you need to use this inside an existing Electron application after the .on('ready') event has been fired.

  const { app } = require("electron");
  const {
    setContainerWidth,
    setGlobalStyles,
    createNotification,
  } = require("electron-custom-notifications");
  
  // OPTIONAL: Set optional container width.
  // DEFAULT: 300
  setContainerWidth(350);

  // OPTIONAL: Set custom styles.
  setGlobalStyles(css`
    * {
      font-family: Helvetica;
    }
    .notification {
      display: block;
      padding: 20px;
      background-color: #fff;
      border-radius: 12px;
      margin: 10px;
      box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
    }
    .notification h1 {
      font-weight: bold;
    }
  `);
  
  const myTitleVar = 'Notification title';
  const myBodyVar = 'Notification body';
  const notification = createNotification({
    content: html`
      <div class="notification">
        <h1>${myTitleVar}</h1>
        <p>${myBodyVar}</p>
      </div>
    `,

    // OPTIONAL: Specify a timeout.
    // timeout: 3000,
  });
  
  // When the notification was clicked.
  notification.on("click", () => {
    console.log("Notification has been clicked");
  });

  // When the notification was closed.
  notification.on("close", () => {
    console.log("Notification has been closed");
  });
  
  // Close the notification at will.
  // notification.close();

Result

alt text

(Notifications stack on top of each other)

Adding Images

To add images, we will load them in base64 encoding. Using relative/absolute paths will most likely not work. Here's an example of a YouTube-styled notification:

const { app } = require("electron");
const {
 setGlobalStyles,
 createNotification,
} = require("electron-custom-notifications");

// Load image in base64 encoding.
const logo = require("fs").readFileSync("youtube.png", "base64");

setGlobalStyles(css`
 * {
   font-family: Helvetica;
 }
 .notification {
   overflow: hidden;
   display: block;
   padding: 20px;
   background-color: #fff;
   border-radius: 12px;
   margin: 10px;
   box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
   display: flex;
 }
 .notification h1 {
   font-weight: bold;
 }
 .notification #logo {
   background-image: url("data:image/png;base64,${logo}");
   background-size: cover;
   background-position: center;
   width: 80px;
   height: 50px;
 }
`);

app.on("ready", () => {
 const notification = createNotification({
   content: html`
   <div class="notification">
     <div id="logo"></div>
     <div id="content">
       <h1>Watch on Youtube</h1>
       <p>This is a notification about a YouTube video.</p>
     </div>
   </div> 
   `,

   timeout: 3000,
 });

 notification.on("click", () => {
   // Open the YouTube link in a browser.
   require("electron").shell.openExternal(
     "https://www.youtube.com/watch?v=M9FGaan35s0"
   );
 });
});

Result

alt text

Adding custom fonts

Same thing as with the images. We will need to use base64 encoding to add them to our styles.

const { app } = require("electron");
const {
 setGlobalStyles,
 createNotification,
} = require("electron-custom-notifications");

const fs = require("fs");

const logo = fs.readFileSync("youtube.png", "base64");
const robotoRegular = fs.readFileSync("Roboto-Regular.ttf", "base64");
const robotoBold = fs.readFileSync("Roboto-Bold.ttf", "base64");

setGlobalStyles(css`
 @font-face {
   font-family: 'Roboto';
   src: url(data:font/truetype;charset=utf-8;base64,${robotoRegular}) format('truetype');
   font-weight: normal;
   font-style: normal;
 }
 @font-face {
   font-family: 'Roboto';
   src: url(data:font/truetype;charset=utf-8;base64,${robotoBold}) format('truetype');
   font-weight: bold;
   font-style: normal;
 }
 * {
   font-family: Roboto;
 }
 .notification {
   overflow: hidden;
   display: block;
   padding: 20px;
   background-color: #fff;
   border-radius: 12px;
   margin: 10px;
   box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
   display: flex;
 }
 .notification h1 {
   font-weight: bold;
 }
 .notification #logo {
   background-image: url("data:image/png;base64,${logo}");
   background-size: cover;
   background-position: center;
   width: 80px;
   height: 50px;
 }
`);

app.on("ready", () => {
 const notification = createNotification({
   content: html`
   <div class="notification">
     <div id="logo"></div>
     <div id="content">
       <h1>Watch on Youtube</h1>
       <p>This is a notification about a YouTube video.</p>
     </div>
   </div> 
   `,

   // OPTIONAL: Specify a timeout.
   // timeout: 3000,
 });

 notification.on("click", () => {
   require("electron").shell.openExternal(
     "https://www.youtube.com/watch?v=M9FGaan35s0"
   );
 });
}); 

Result

Our notification has the best font in the world.

alt text

Animations

You can write up your own CSS animations in setGlobalStyles(), or you can use Animate.css library, which is already included and ready to use in this library. Example animated notification content:

<div class="notification animated fadeInUp">
  <div id="logo"></div>
  <div id="content">
    <h1>Watch on Youtube</h1>
    <p>This is a notification about a YouTube video.</p>
  </div>
</div> 

Check out Animate.css for more animations

Result

alt text

To-do

  • [ ] [Security] Use preload instead of allowing Node access and disabling context isolation in renderer.
  • [ ] [Enhancement] Allow the container to be placed in different parts of the screen (currently only bottom-right).
  • [ ] [Enhancement] Make setGlobalStyles replace styles instead of appending them.