Friday, June 26, 2020

How to create a desktop app from website in 10 minutes?



desktop application from website


Building a Cross Platform Desktop Application (i.e.. App that can run on Windows, Linux, and Mac os) helps to reduce the development time and cost. Electron is one of the best and known frameworks to develop desktop applications. 
Many famous applications like VS Code, Slack, Figma, etc are built on Electron.
The best part about Electron is, you need not learn any new language, you can simply write JavaScript, HTML, or use a framework like REACT, VUE, and ANGULAR and compile it to a desktop app, or If you have a website hosted you can simply provide the URL of the website to create a desktop application.
Today we will see how to create a desktop application from a website hosted on the web and some must-have features to get you started.

If you have no time or wanna know what we are going to build then I recommend clone/download my desktop-app-in-minutes repo and replace the https://www.blog.guidefather.in URL with your websites URL.

What we will cover?

  • What is electronJS?
  • Create a desktop app from the website URL.
  • Create a Custom Header in electron app.
  • Using npm modules in the electron app.
  • Managing app events 
  • Distribution of an electron app
  • Pros and Cons of electrons
app preview

What is electronJS?

With the help of ElectronJs one can build cross-platform desktop applications with HTML, JavaScript, and CSS. It was introduced in 2013 to make cross-platform text-editors, later its scope was extended to build other utility apps. Electron has chromium in it
Electron has two processes 
  • Main Process: It manages the bootstrapping the application and lifecycle events like starting, quitting, etc. This main process is responsible for interacting with the native GUI of the Operating System. It creates the GUI of your application.
  • Rendering Process: It is created by the main process and its main purpose is to render the UI.

Create a desktop app from the website URL.

Before proceeding you need to have node and npm install in your system.
Steps to create a desktop app.
  • Create a folder with the name you want and type following commands
    npm init -y
    npm i electron --save-dev
  • add a start script in package.json
    "start":"electron ."
 You can get the complete project code from my GitHub Repository.

const { app, BrowserWindow, Menu, shell } = require('electron');

function createWindow() {
const win = new BrowserWindow({
width: 1100,
height: 800,
webPreferences: {
nodeIntegration: true
}
})
// win.webContents.openDevTools() //Open dev tools

// To open the file from a local directory.
// win.loadFile('index.html')

//open url
win.loadURL("https://www.blog.guidefather.in")


}

//lauch view when electron is ready
app.whenReady().then(createWindow)

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})

// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

   main.js

This will open https://www.blog.guidefather.in in an application, from which you can interact.
BrowserWindow runs its own renderer process. This renderer process will take the HTML, CSS, and JavaScript and render it to the window.

win.webContents.openDevTools()
It is used to open dev tools in the application for debugging purposes.

If you have the code in ANGULAR, REACT, VUE, or any other framework which can be compiled down to HTML, CSS, and JavaScript you can create an application by providing a path to the dist folder
win.loadFile("path_to_dist")
By using the above code you will have a basic desktop application.

Create a custom header in electron app

By writing the above code you will have a desktop application but with a default header of your operating system. You can override the default headers and create custom headers by using the MENU module of electron.

const menu = Menu.buildFromTemplate([{
label: "Menu",
submenu: [
{
label: "Disclaimer",
click() {
utility.openModel(win, "Disclaimer")
}
},
{
label: "View Article",
click() {
//open external links
shell.openExternal("https://www.blog.guidefather.in")
}
},
{ type: "separator" },//introduce a gap in menu
{
label: "Exit",
click() {
app.quit() //quit application
}
}
]

}, {
label: "History",
accelerator: "CommandOrControl+H", //shortcut
click() {
utility.openModel(win, "History")
}
}])
Menu.setApplicationMenu(menu)
By implementing the above code you will have a menu like this
Menu Preview
 Menu.buildFromTemplate takes an array of objects which will be displayed as the menu. Each Object has a mandatory field label which will be displayed as the title of the menu. You can have sub-menu using submenu inside each object.
To perform click event you have to declare a function click.
You can specify shortcut keys to perform the task by using an accelerator. As you can see I have used CommandOrControl+H to open the history tab.

Events 

app.quit() : This will close the application 
shell.openExternal() :  To open External links 
openModal: I've created a custom function to open models in utility.js
function openModel(parent, pageType) {
modal = new BrowserWindow({
width: 600,
height: 700,
title: 'Info',
frame: false,//remove headers
backgroundColor: '#2e2c29',
parent: parent,//to specify the parent
webPreferences: {
nodeIntegration: true
}
});
// modal.webContents.openDevTools()
switch (pageType) {
case "Disclaimer":
modal.loadFile("./src/info.html")
break;
case "History":
modal.loadFile("./src/history.html")
break;
}
modal.on('close', function () {
modal = null;
});
}

Using NPM module in the electron app.

You can use the NPM module in the electon app in the same way as you use in node.js, but the best part is if you specify nodeIntegration = true in BrowserWindow then you can access Node.js in HTML files.
To access Node.js in HTML file, simply declare a script tag in the HTML page and start writing Node.js 
<script>
const remote = require("electron").remote;
const utility = require("../utility")
document.querySelector("#close-info").addEventListener("click", function () {
remote.getCurrentWindow().close() //get current window and close it
})
utility.getHistory().then(history => {
history.forEach(d => {
document.getElementById("hist-row")
            .insertAdjacentHTML('beforeend',
                                  `<tr><td>${d[0]}</td><td>${d[1]}</td><tr>
                                `);
});
})
</script>

As you can see I have imported utility using require statement to call utility functions.

Managing App Events

You can monitor the events performed by the user in the application by app events. I've used this feature to monitor the history of the user by writing it to a CSV file.
win.webContents give access to the running process.
win.webContents.on("will-navigate", function (e, url) {
utility.writeHistory(url)
})

You can check all the option here
To specify the directory where to save the file I've used 
const historyPath= (app || remote.app).getPath("userData") + "/history.csv";
getpath will return the path depending on the operating system. If you don't specify this then your code may not runs all platforms.

Distribution of electron app

After development comes the most tricky part compiling the OS-specific builds. To build an application in electron I recommend using electron-builder
  • Install electron builder
    npm i electron-builder --save-dev
  • Add icons 
    create a folder in the project directory, name it build and place icon with the name of icon.png and dimension of 256 X 256.
  • Modify package.json, electron builder take the details from package.json file. 
    {
    "name": "gview",
    "version": "1.1.0",
    "description": "website to desktop app in 5 mins",
    "main": "main.js",
    "scripts": {
    "start": "electron .",
    "build:linux": "electron-builder --linux deb",
    "build:win": "electron-builder --win", "build:mac": "electron-builder --mac"
    },
    "keywords": [],
    "author": {
    "name": "Service",
    "email": "service.b@blog.guidefather.in"
    },
    "license": "ISC",
    "devDependencies": {
    "electron": "^9.0.5",
    "electron-builder": "^22.7.0"
    },
    "dependencies": {
    "csv-writer": "^1.6.0"
    },
    "homepage": "https://blog.guidefather.in",
    "nsis": {
    "deleteAppDataOnUninstall": true,
    "uninstallDisplayName": "app"
    }
    }
replace the details with you own.
  • run commands
    npm run build:linux for Linux
    npm  run build:win for windows
    npm  run build:mac for Mac
    for more details and info you can check the link 

Pros and Cons of electron App

PROS

  • You need not to learn an extra language or framework. If you have knowledge of HTML, CSS and JavaScript you can build cross-platform apps in few minutes.
  • Its has great documentation and APIs which help you achieve the desired results and access native APIs easily.
  • You can develop without worrying about platform compatibility.
  • NPM support, you have access to the huge libraries of npm, using which you can achieve anything.

CONS

  • Build size is huge, Even for small application build size is huge because it has the chromium engine built in it.
  • Hight CPU utilization, Electron consumes a high amount because it launches a separate instance of chromium every time a new window loads.
  • Build Complications, Building OS-specific installable may not give desired results. You will most likely face issues with icons, writing files, etc.. because each and every system behaves differently.

Conclusion 

ElectronJs is great if you are not developing something out of the box or CPU intensive apps. With nice documentation and support electronJs is still evolving. I recommend to clone my GitHub repo and check CPU utilization, build size etc.. and make sure electron is best for your need.

T̳h̳a̳n̳k̳ y̳o̳u̳



Monday, June 22, 2020

Solution: Window can't be installed in this disk.The selected disk has MBR partition table.On EFI systems, windows can only be installed to GPT disk.



" Window can't be installed in this disk. The selected disk has MBR partition table. On EFI systems, windows can only be installed to GPT disk."
Add caption
Window can't be installed in this disk. The selected disk has MBR partition table.
On EFI systems, windows can only be installed to GPT disk."



Welcome noobs, to your GuideFather, Suddenly you woke up and thought of installing Windows 10 in your older window 7 system, you do exactly as instructed in our article but suddenly you see an annoying message while selecting the Drive: Window can't be installed in this disk. The selected disk has MBR partition table.On EFI systems, windows can only be installed to GPT disk. Or for any other reason, you may want to convert your MBR partition to GPT. You are at the right place.

Step 1:

Open command prompt
Don't get confused, You just need to Hold SHIFT KEY and Press F10 i.e SHIFT+F10 at the exact screen you are getting the error

Step 2:

Now You have access to command prompt , which is great but you have to know the steps and commands to use otherwise what's the use of getting a key of your dad's car if you don't know how to drive.
so just type the following commands:

diskpart
diskpart is basically a command tool that uses all the commands related to your drives or disk.
after you hit that enter button you have to type next command:

list disk
now you have list all the DISKS, not the DRIVES, even the disk you are using as a bootable media.
Identify the disk you want to install Windows most probably the disk 0.

Warning: The next steps will erase everything form that entire DISK not Partition or Drives but the entire DISK make sure you have a backup of all your important data

Now  type :
select disk 0(or the disk you want to install the windows in)
After you press enter its time to clean everything in the disk so by putting the rock in your heart type:

clean
this time you press enter there is no going back
now type:

convert gpt

then execute the exit command twice.


In summary:
  1. Shift+F10
  2. diskpart
  3. list disk
  4. select disk 0
  5. clean
  6. convert gpt
  7. exit
  8. exit





now press the refresh button on the panel
you will see one unallocated space equal to your disk,that's your disk converted in to GPT partition.
now create as many drives as you want in it as it's converted into GPT partiton table.
then select drive to install the windows, You won't get any errors.



Sunday, June 14, 2020

How to detect Browser is online or offline?



no internet

Let the user know that he/she is offline is not only a good feature but it helps developers to avoid unexpected conditions and handle errors gracefully. By detecting the client has gone offline you can perform all the security measures to ensure the security of your application.
There are many ways to detect it but I will show you four ways to detect that the client has gone offline and will discuss the pros and cons of each approach. 

Approaches to detect client is offline.

I've created a project to explain all the above-mentioned approaches using Typescript, JavaScript, HTML, and UIKIT (for styling). You can get the code from my GitHub repository 
no network project

Client-Side Approaches

JavaScript has awesome APIs to detect that the client has an internet connection or not. These APIs are easy to use, faster, and less expensive than Server-side Approaches.

Event Listener 

In this, we add event Listeners to the window object which will fire when the client goes offline or online.
window.addEventListener('online', function () {
console.log("online")
})
window.addEventListener('offline', function () {
console.log("offline")
})

Navigator is a widely supported BOM (Browser Object Model ) APIs by browsers which can detect network connectivity easily and directly.
setInterval(() => {
if (navigator.onLine) {
console.log("online")
} else {
console.log("offline")
}
}, 1000);

SetInterval is used to check the internet every 1 second because unlike the event listener approach it doesn't react the change automatically.

Pros of Client-Side Approaches

  • Very fast as compared to server-side approaches  
  • Easy to use and setup
  • No-load on server

Cons of Client-Side Approaches 

  • Server will have no information of clients internet connectivity.
  • Both approaches check that the client is connected to a network( not internet ) or not, that is client may be connected to a local network that has no access to the internet. 
    If you detect the client is offline that means the client doesn't have internet connection but if it detects online that doesn't mean that browser can access the internet.
  • Browser support is always an issue, these approaches may not work in older browsers and few modern browsers.
    My personal experience is that Navigator more widely supported than the event listener approach.

Server-Side Approaches 

Server Side approaches are harder to set up than client-side approaches but they are not dependent on the client's browser.

API-Calling

This is the most used approach as it doesn't require any additional dependency and easier to set up than other server-side approaches. The idea is simple just call an API regularly after a certain interval of time if you get the response successfully then the client is connected to the internet if the call result in error then the client is offline.

setInterval(() => {
makeApiCall()
}, 1000);
function makeApiCall() {
axios.get("/checknet").then(
d => console.log("online")
).catch(
e => {
console.log("offline")
}
)
}

Sockets

Sockets allow bidirectional, real-time, and event-based connection between client and server. 
Sockets have two predefined events connect and disconnect which fired whenever the client gets connected and disconnected from the server.

let interVal=null;
const socket=io()
socket.on("connect",function(){
updateIfRequire("online");
clearInterval(interVal)
})
socket.on("disconnect",function(){
interVal=setTimeout(() => {
updateIfRequire("offline")
}, 100);
})

You may be wondering, why setTimeout and clearInterval? 
Because Sockets are very fast and in real live projects, small errors can occur any time which may interrupt the socket connection, however, sockets will try to reconnect and establish the connection within few milliseconds that's why I have used setTimeout to update the state after 100ms, meanwhile, if the sockets get connected just clear the setTimeout to stop code from updating the state.

Pros of Server-side Approach

  • No dependency on the client's browser hence no issue of browser support.
  • Reliable, unlike client-side approaches it detects that the browser has the internet or not.
  • Server will know the state of the client.

Cons of Server-side Approach

  • Hard to set up as compared to the client-side approach.
  • Introduce extra load to the server especially API calling approach.
  • Slow as compared to the client-side approach.

Conclusion

Different approaches are useful in different scenarios. Clone my GitHub repo and check which approach best suits your case.
Generally, use client-side approaches when you need not to validate any case, just need to show that the user has no internet connection, but if you need to validate the user before future proceeding like before uploading important files to the server, use server-side approach.

🅣🅗🅐🅝🅚 🅨🅞🅤

Tuesday, June 9, 2020

Host website/api from local system | ngrok


Ngrok workflow
Have you ever tried to host your own website? If yes,then you must agree that it's really a time consuming, expensive, and tedious task when it requires frequent changes to satisfy your client or colleagues ðŸ˜“.

Ngrok is a cross-platform service that enables you to expose your local development server to the internet.

You need not have any domain, server, or IT knowledge to use it. It is one of the most important tool when working remotely. You can expose your API or website to the internet without pushing your code to any server and the best part is all this for free.
This article will have the following sections:

How Ngrok works

Ngrok works as a mediator between the client and your system. Ngrok provides you an URL( say xyz.ngrok.io) that is mapped to the port of your system. Whenever someone hit the URL xyz.ngrok.io it will be forwarded to the port you mapped and the response will be forwarded back to the client 
Basically, Ngrok exposes a local server behind the NAT(Network Access Translation) and firewall to the public internet over a secure tunnel.
Setting up ngrok is one of the easiest things in the world. I have a project running from my previous article in my local environment at the port 3000.
local project

Setup Ngrok in Ubuntu/Windows

  • Navigate to https://ngrok.com/download and download a zip file compatible with your OS.
  • Extract it, you will get an executable file.
  • Open a terminal in the same directory and type the following command.
    ./ngrok http <port>
    example : ./ngrok http 3000
  • You will get a URL from ngrok to your website from the public network 

    Ngrok Terminal
           
Website Served from ngrok

Ngrok Dashboard

You need not register to Ngrok but if you want to view your active sessions and URLs you can use the Ngrok Dashboard
  • Register and log in to the website.
  • Navigate to Getting Started -> Setup & Installation.
  • You should see something like this.  

    ngrok Dashboard
  • Go to terminal and type
    ./ngrok authtoken <you_token>
    to connect view all your sessions in a dashboard 
  • Once you added this Ngrok will detect the tunnel itself and show you your active tunnels under Status -> Tunnels.

If you want you can get more info from here
If you want to use the service with your custom domain then you have to refer to their paid plans. Paid plans also provide advanced services like authentication and IP restrictions etc.

.... ƃuᴉpɐǝɹ ɹoⅎ noʎ ʞuɐɥʇ



 

Sunday, June 7, 2020

Sending Emails By SendGrid | Domain Authentication


Sending Emails By SendGrid | Domain Authentication
SendGrid provides two methods to verify the sender as discussed in my previous article.
  • Domain Authentication 
  • Single Sender Verification 
We have already covered the Single Sender Verification method. Today we will check the Domain Authentication process.

Pros and Cons of Domain Authentication.

Pros : 
  • You can send emails via any email address of your domain whether that email id exists or not, Example guidefather@yourdomain.com.
  • One time setup, In single sender method you have to verify the other emailId again if you want to send mail by another email Id.
Cons :
  • You need a domain to use this method.
  • Setup is quite complex for a person from a non-technical background.
  • Setup may require time.

Setup Domain Authentication 

  • Navigate to Settings -> Sender Authentication from the left panel. 
  • Click on Get Started under Authenticate Your Domain section if it's your first domain, If you already have added a domain then you have to click on Authenticate Domain. You will be redirected to a new page.

    Sender AuthenticationSelect your domain provider and click on next.
  • Enter the domain or subdomain from which you want to send mail, Under Advance options, you can check DKIM settings and return path to avoid spam but these are not necessary for now.
    Enter Domain
  • On the next screen, you can see the DNS records that you have to add in your domain provider
    DNS records
  • Go to your DNS provider and add three CNAME records provided  by SendGrid
    NOTE: remove your primary domain name from HOST name
    For example, I am using my.guidefather.in  so the records generated will be like 
    xyz.my.guidefather.in while adding your hostname in domain provider you have to paste only xyz.my
    Adding records to domain provider
     
  • Wait for some time and click on the verify button. It may take an hour or more to verify the records 
To check that you have added the records correctly go to DNS Checker select CNAME from dropdown and enter the hostname provided by SendGrid in my case it will be xyz.my.guidefather.in 
Dns Checker

To generate API keys or send mail via SendGrid you can check this article .

Thank you for reading