SumitK27 / Learn-Electron

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Electron

wakatime

A follow-along repository of StephenGrider's Course Electron for Desktop Apps The Complete Developer's Guide

  1. About
    1. Limitation of Browser
    2. Difference
    3. Why?
  2. Installing Electron
  3. Setting Up
  4. Event Listeners
    1. Ready
    2. Click
    3. Right Click
    4. Blur
  5. Power of Electron
  6. IPC
    1. IPC Difference
    2. Enable Node Modules on Renderer
    3. Send data from Renderer to Main
    4. Send Data from Main to Renderer
  7. Custom Menu
  8. Add New Window
  9. Function based on Environment
  10. Garbage Collection
  11. Roles
  12. Browser Window Configuration
    1. Web Preferences
    2. Window Resolution
    3. Frame
    4. Window Resizing
    5. Show
    6. Skip Taskbar
  13. Tray
    1. Create Tray
    2. Adding Event Listener
    3. Tool Tip
    4. Context Menu
  14. Bounds
    1. Get Bounds
      1. Through Window Position
      2. Through Event
    2. Set Bounds

About

  • Open-source JavaScript Framework.
  • Developed by GitHub in 2014.
  • Used to build desktop apps with the technologies used to make websites (HTML, CSS, JavaScript).
  • Let's you build cross-platform Desktop apps.
  • Is just a Chromium based window that can render webpages.
  • Allows you to integrate any frontend framework eg. React, Angular, Vue, etc. in your apps.

Limitation of Browser

  • Can't access your hard drive (unless you feed a specific file)

Difference

Electron vs Desktop App

Why?

Why

Installing Electron

$ mkdir project-name
$ cd project-name
$ npm init -y
$ npm install electron

Setting Up

  • Add electron . as the start script in your package.json
...
"scripts: [
    "start": "electron ."
]
...
  1. Create index.js file.
  2. Import electron module (with require).
  3. Extract app & BrowserWindow object from electron.
  4. Add ready event listener on app.
  5. Create new BrowserWindow object in the callback function.
// Import electron
const electron = require("electron");

// Extract app & BrowserWindow object
const { app, BrowserWindow } = electron;

// Add `ready` event listener on app
app.on("ready", () => {
    // Creating new BrowserWindow object
    const mainWindow = new BrowserWindow({});

    // Serve `index.html` file on the main window
    mainWindow.loadURL(`file://${__dirname}/index.html`);
});

Event Listeners

  • Allows you to listen for an event on a particular window or app.

Events

Ready

  • ready is used when window is ready (completely rendered).
mainWindow.on("ready", () => {
    console.log("You are ready!");
});

Click

  • click is used when user clicks on the window.
mainWindow.on("click", () => {
    console.log("You Just Clicked!");
});

Right Click

  • right-click is used when user right clicks on the window.
mainWindow.on("right-click", () => {
    console.log("You Just Right Clicked!");
});

Blur

  • blur is used when user looses it's focus from the window.
mainWindow.on("blur", () => {
    console.log("You Lost Focus!");
});

Power of Electron

  • Main Window = Node + Web Browser
  • Allows you to use Node Modules in the Main Window Main Window

IPC

  • Inter Process Communication.
  • Allows you to communicate between different processes of the Electron app. Inter Process Communication

IPC Difference

  • There are some differences between the methods to send and receive the data through IPC on Electron App and Web App side. IPC Difference

Enable Node Modules on Renderer

let mainWindow;
app.on("ready", () => {
    mainWindow = new BrowserWindow({
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false,
        },
    });

    mainWindow.loadFile("index.html");
});

Send data from Renderer to Main

Renderer

const electron = require("electron");
const { ipcRenderer } = electron;

const formElement = document.querySelector("form");
formElement.addEventListener("submit", (event) => {
    event.preventDefault();

    const { path } = document.querySelector("input").files[0];

    // Send file path with custom event name to Electron
    ipcRenderer.send("video:submit", path);
});

Main

// Get event data from the Web
ipcMain.on("video:submit", (event, path) => {
    console.log(path);
});

Send Data from Main to Renderer

Main

mainWindow.webContents.send("video:metadata", metadata.format.duration);

Renderer

// Receive Data from Main
ipcRenderer.on("video:metadata", (event, duration) => {
    const resultElement = document.getElementById("result");

    resultElement.innerHTML = `Video is ${duration} seconds`;
});

Custom Menu

  • Adding a Custom menu removes all the predefined functionality of the default Electron menu.
  • Every Menu Item has a label, optionally an accelerator, a sub-menu and a click function.
const { app, BrowserWindow, Menu } = require("electron");

let mainWindow;
app.on("ready", () => {
    ...
    // Use Menu from the Menu Template
    const mainMenu = Menu.buildFromTemplate(menuTemplate);
    // Add Menu to the Application
    Menu.setApplicationMenu(mainMenu);
});

// Create a Menu Template
const menuTemplate = [
    {
        label: "File",
        submenu: [
            {
                label: "Add ToDo",
            },
            {
                label: "Quit",
                // Platform based hotkeys
                accelerator:
                    process.platform === "darwin" ? "Command+Q" : "Ctrl+Q",
                click() {
                    app.quit();
                },
            },
        ],
    },
];

Add New Window

  • Add a new window on click of a menu item.
let addWindow;
...
function createAddWindow() {
    addWindow = new BrowserWindow({
        width: 300, // set window width in pixel
        height: 200, // set window height in pixel
        title: "Add New Todo", // set window title
    });

    addWindow.loadFile("add.html");
}

// Create a Menu Template
const menuTemplate = [
    {
        label: "File",
        submenu: [
            {
                label: "Add ToDo",
                click() {
                    createAddWindow();
                },
            },
        ],
    },
];

Function based on Environment

  • Show Development Tools on if its Development environment.
if (process.env.NODE_ENV === "development") {
    menuTemplate.push({
        label: "View",
        submenu: [
            {
                label: "Toggle Developer Tools",
                accelerator:
                    process.platform === "darwin"
                        ? "Command+Alt+I"
                        : "Ctrl+Shift+I",
                click(item, focusedWindow) {
                    focusedWindow.toggleDevTools();
                },
            },
        ],
    });
}

Garbage Collection

  • Closing a window doesn't frees up the memory in Electron.
  • We have to manually specify it to work the way JavaScript's Garbage collection works.
function createAddWindow() {
    ...
    // Delete the Add Window
    addWindow.on("closed", () => {
        addWindow = null;
    });
}

// Get todo from Add Window and send it to Main Window
ipcMain.on("todo:add", (event, todo) => {
    mainWindow.webContents.send("todo:add", todo);

    // Close the add Window
    addWindow.close();
});

Roles

  • There are several predefined roles that are made available by Electron.
  • These roles allow to patch things up easily in your app.
  • eg. adding back the reload menu item to your custom menu without need to create one again.
menuTemplate.push({
    label: "View",
    submenu: [{ role: "reload" }],
});

Browser Window Configuration

Web Preferences

webPreferences: {
    nodeIntegration: true, // Allows to integrate node modules
    backgroundThrottling: false, // Prevents from app getting freezed in the background
},

Window Resolution

  • We can set the default width and height of the window with the keys width and height and set it to the pixel value.
mainWindow = new BrowserWindow({
    width: 300,
    height: 500,
});

Frame

  • The frame contains the menu bar and the title bar to minimize, full-screen or close the application.
  • frame can be set to false if we don't want to display the frame.
mainWindow = new BrowserWindow({
    frame: false,
});

Window Resizing

  • We can set whether we want the user to resize our app screen or not.
  • resizable is the flag used to enable or disable the resizing of the window.
  • Default value is true.
mainWindow = new BrowserWindow({
    resizable: false,
});

Show

  • show allows you to either show or hide the window when the application is launched.
  • By default show is set to true.
mainWindow = new BrowserWindow({
    show: false,
});

Skip Taskbar

  • skipTaskbar allows you to hide the window's (application's) Taskbar Icon.
  • By default skipTaskbar is set to false.
mainWindow = new BrowserWindow({
    skipTaskbar: false,
});

Tray

Create Tray

  • Electron has a Tray object which allows you to create a tray icon for your application.
  • Every Tray has an icon.
  • Icon doesn't needs to have the specific resolution indicator (eg. icon@2x.png), Electron adjusts the icon to be used automatically.
// Import Tray from electron
const { Tray } = require("electron");

app.on("ready", () => {
    ...
    const iconName = "windows-icon.png";
    const iconPath = path.join(__dirname, `./src/assets/${iconName}`);
    // Adding Tray Icon of Application
    new Tray(iconPath);
});

Adding Event Listener

let tray;

app.on("ready", () => {
    ...
    tray = new Tray();

    // Click Event Listener on Tray
    tray.on("click", () => {
        if (mainWindow.isVisible()) {
            mainWindow.hide();
        } else {
            mainWindow.show();
        }
    });
})

Tool Tip

  • ToolTips are used to display the short information whenever we hover on some object.
  • setToolTip method can be used on the tray object to set the tool tip.
const tray = new Tray();

// Setting tooltip
tray.setToolTip("Timer App");

Context Menu

  • Context Menu can be added to the Tray with the help of popUpContextMenu method on tray object.
  • popUpContextMenu takes Menu Template as a parameter to display the menu items in the context menu.
tray.on("right-click", () => {
    // Create context menu items
    const menuConfig = Menu.buildFromTemplate([
        {
            label: "Quit",
            click: () => {
                app.quit();
            },
        },
    ]);

    // Adding Context Menu
    tray.popUpContextMenu(menuConfig);
});

Bounds

  • Allows you to see the position of where the event happened on the screen.
  • Bounds are automatically passed to the callback function with event by electron.

Get Bounds

Through Window Position
const { height, width } = mainWindow.getBounds();
Through Event
tray.on("click", (event, bounds) => {
    console.log(bounds.x, bounds.y);
    // Windows: Somewhere around (1283, 824) -> (1315, 784) ie. lower right (position of tray on taskbar)
    // MacOS: top-right
});

Set Bounds

  • We can set the position of the window with setBounds().
  • It takes x position, y position to be displayed at and the width & height of the window to be displayed.
mainWindow.setBounds({
    x: xPosition,
    y: yPosition,
    width: widthValue,
    height: heightValue,
});

About


Languages

Language:JavaScript 89.1%Language:HTML 10.9%