1.0.5 • Published 7 months ago

electron-notifications-srsolutions v1.0.5

Weekly downloads
-
License
ISC
Repository
-
Last release
7 months ago

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.
1.0.5

7 months ago

1.0.4

7 months ago

1.0.3

8 months ago

1.0.2

8 months ago

1.0.1

8 months ago