The renderer.js file receives the input from the user, for example, when a user clicks on the Add folder
button, in response the renderer.js shows the directory picker dialog box.
Lets start writing the renderer.js file. First we’ll import the Electron’s dialog
api.
const {dialog} = require('electron').remote let dir = dirObject let dirs = [] let isStarted = false let startBtn = document.querySelector('#startBtn') startBtn.addEventListener('click', () => { if (dirs.length === 0) return isStarted ? pauseApp() : startApp() }) let addBtn = document.querySelector('#addBtn') addBtn.addEventListener('click', addFolder) let pathsDiv = document.querySelectory('#paths') let pathsDivHead = document.querySelector('#pathsHead')
const {dialog} = require('electron').remote
Load the Electron’s dialog api to display directory picker or browser.
let dir = dirObject
The dir
object will hold the information of a folder added by the user i.e. its type included
or excluded
, its path and so on. We’ll create this class later in this tutorial.
let dirs = []
The dirs
array stores the dir
objects. Whenever a folder added for scanning, the app create a new instance of dir
object by calling it with folder path and then store that object in the dirs
array.
let isStarted = false
The isStarted
stores the app state – running or stopped. (See startBtn event function).
let startBtn = document.querySelector('startBtn')
Selects the starBtn
from the index.html. We’ll use this button to start or pause the application.
startBtn.addEventListener('click', () => {
Add an event listener to the startBtn
that fires when javascript detects a click on startBtn
button.
if (dirs.length === 0) return
The callback function checks the dirs
array, if array is empty then the further code will not execute due to not a single path available for scanning.
isStarted ? pauseApp() : startApp()
The ternary operator calls the pauseApp
if isStarted
value is true to pause the application or startApp
if the isStarted
value is false
to start the application.
let addBtn = document.querySelector('#addBtn')
Selects the addBtn
from the index.html. We’ll use this button to browse our file system with the help of Electron’s dialog
.
addBtn.addEventListener('click', addFolder)
Add an event listener to the addBtn
that fires when javascript detects a click on addBtn
button. The addFolder
function will call in response.
let pathsDiv = document.querySelectory('#paths')
Select the div from the index.html to display the folders paths selected by the user using add folder button and also show some option such as delete path button and change the type of path to included
or excluded
button.
let pathsDivHead = document.querySelector('#pathsHead')
Select this div from the index.html. This div shows the headings content for the pathsDiv. By default it is hidden, we’ll unhide it when there is at-least one dir
object exist in the dirs
array. It means, at least one path exist for scanning to display the paths heading content.
Creating startApp function
function startApp(){ startBtn.innerHTML = '<span class="red">⏸</span> Pause search' isStarted = true }
Currently this function has only two lines of code, one for changing the text of startBtn
to Pause search
and the other line change the value of isStarted
. The isStarted
hold the current state of application and its value must be change upon start or pause of the application.
Creating pauseApp function
function pauseApp() { startBtn.innerHTML = '<span class="green">▶</span> Start search' isStarted = false }
Similarly the pauseApp
function also contains the two lines code to change the text of startBtn
and value of isStarted
.
The above two function are currently not doing a tough job but we’ll write more code to really start or pause the app later.
Creating the addFolder function
function addFolder(){ if (isStarted) return let options = { properties: ['openDirectory', 'multiSelections'] } dialog.showOpenDialog(options, (paths) => { if (!paths) return paths.forEach(path =>{ let exist = dirs.some((dir) => { return dir.path == path }) if (exist){ alert(path + ' already added in the list') return; } new dir(path); }) }) }
The addFolder
function displays the directory picker. It first checks the current state of application using if (isStarted) return
code, and displays the dialog box (directory picker) if the application is not running.
The dialog
box return an array of file paths chosen by the user, we’ll retrieve each path with the help of forEach loop and test the each path if it already exist in dirs
array, using javascript’s some()
method. The some()
method tests whether at least one element in the array passes the test implemented by the provided function. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some.
If path is not already exist in dirs
array, we’ll create a new instance of new dir(path)
object by calling it with path
argument.
Creating the dirObject
class
The dirObject
object has two properties, path
(the folder path) and isIncluded
. The isIncluded
tells the app to scan this path
if its value is true
.
For example, we want to scan a folder d:\brainbell
for duplicate file search but there is a folder d:\brainbell\backups
which we want to exclude from the scanning.
To accomplish this, we must add both folders and then change the type of d:\brainbell\backups
folder to excluded
, which will change the value of isIncluded
to false
, now d:\brainbell\backups
folder and its sub-folders will not scan.
The dir
object has some additional code which will use to make some buttons, for example, the delete
and type
buttons. Each button has an event listener, which fires a callback function when clicked.
function dirObject(path){ this.path = path this.isIncluded = true dirs.push (this) pathsDivHead.className = '' let textNode = document.createTextNode(path); let del = document.createElement('span') del.className = 'delDir'; del.innerHTML = '🗙' let type = document.createElement('span'); type.className = 'typeDir' type.innerHTML = 'included'; let div = document.createElement('div') div.appendChild(del) div.appendChild(type) div.appendChild(textNode) pathsDiv.appendChild(div) del.addEventListener('click', () => { if (isStarted) return pathsDiv.removeChild(div) let index = dirs.indexOf(this) if (index !== -1) dirs.splice(index, 1) if (dirs.length === 0 ) pathsDivHead.className = 'hide'; }) type.addEventListener('click', () => { if (isStarted) return this.isIncluded = !this.isIncluded if (this.isIncluded){ type.className = 'typeDir' type.innerHTML = 'included' } else { type.className = 'typeDir typeDirDisable' type.innerHTML = 'excluded' } }) }
Download project files:
* index.html
* main.js
* style.css
* renderer.js
* logo.png
Duplicate file finder demo
Version 1.0.0