class: split-30 nopadding background-image: url(https://cloud.githubusercontent.com/assets/4231611/11023040/67004252-86a0-11e5-88cb-87a74f7912e4.jpg) .column_t2.center[.vmiddle[ .fgtransparent[ #
] ]] .column_t2[.vmiddle.nopadding[ .shadelight[.boxtitle1[ # JS - Electron ### [Eueung Mulyana](https://github.com/eueung) ### http://eueung.github.io/js/electron #### JS CodeLabs | [Attribution-ShareAlike CC BY-SA](https://creativecommons.org/licenses/by-sa/4.0/) #### ]] ]] --- class: column_t1 middle .fonth3[ .tab1.fullwidth[ | Agenda | |:-------------:| | Electron Quick Start, Boilerplate | | Angular.JS Todo @ Electron | | Electron + Photon | | Photon Angular Todo-App | ]] --- class: split-30 nopadding background-image: url(https://cloud.githubusercontent.com/assets/4231611/11023040/67004252-86a0-11e5-88cb-87a74f7912e4.jpg) .column_t2.center[.vmiddle[ .fgtransparent[ #
] ]] .column_t2[.vmiddle.nopadding[ .shadelight[.boxtitle1[ # Electron Quick Start ### [atom/electron-quick-start](https://github.com/atom/electron-quick-start) ]] ]] --- class: column_t1 middle .figstyle1[ ![](images/fig01.jpg) ] .center[package.json + main.js + index.html] --- class: split-50 nopadding .column_t2[.vmiddle[ ``` { "name": "electron-quick-start", "version": "1.0.0", "description": "A minimal Electron application", * "main": "main.js", "scripts": { "start": "electron main.js" }, "repository": { "type": "git", "url": "git+https://github.com/atom/electron-quick-start.git" }, "keywords": [ "Electron", "quick", "start", "tutorial" ], "author": "GitHub", "license": "CC0-1.0", "bugs": { "url": "https://github.com/atom/electron-quick-start/issues" }, "homepage": "https://github.com/atom/electron-quick-start#readme", * "devDependencies": { * "electron-prebuilt": "^0.36.0" * } } ``` .center[**package.json**] ]] .column_t1[.vmiddle[ ``` 'use strict'; const electron = require('electron'); const app = electron.app; const BrowserWindow = electron.BrowserWindow; //-------------------------------------- let mainWindow; //-------------------------------------- app.on('window-all-closed', function() { if (process.platform != 'darwin') { app.quit(); } }); //-------------------------------------- app.on('ready', function() { mainWindow = new BrowserWindow({width: 800, height: 600}); * mainWindow.loadURL('file://' + __dirname + '/index.html'); mainWindow.webContents.openDevTools(); mainWindow.on('closed', function() { mainWindow = null; }); }); ``` .center[**main.js**] ]] --- class: split-50 nopadding .column_t1[.vmiddle[ #Electron Quick Start ### package.json + main.js + index.html ]] .column_t2[.vmiddle[ ```html
Hello World!
*
Hello World!
* We are using node , * Chrome , * and Electron . ``` ]] --- class: split-30 nopadding background-image: url(https://cloud.githubusercontent.com/assets/4231611/11023040/67004252-86a0-11e5-88cb-87a74f7912e4.jpg) .column_t2.center[.vmiddle[ .fgtransparent[ #
] ]] .column_t2[.vmiddle.nopadding[ .shadelight[.boxtitle1[ # Electron Boilerplate ### [sindresorhus/electron-boilerplate](https://github.com/sindresorhus/electron-boilerplate) ]] ]] --- class: column_t1 middle .figstyle1[ ![](images/fig02.jpg) ] .center[package.json + index.js + index.html + index.css] --- class: split-50 nopadding .column_t2[.vmiddle[ ## package.json ``` { "name": "app", "productName": "App", "version": "0.0.0", "description": "", "license": "MIT", "repository": "user/repo", "author": { "name": "", "email": "", "url": "" }, "electronVersion": "0.36.0", "scripts": { "test": "xo", "start": "electron .", "build": "electron-packager . $npm_package_productName --out=dist --ignore='^/dist$' --prune --asar --all --version=$npm_package_electronVersion" }, * "files": [ "index.js", "index.html", "index.css" ], "keywords": [ "electron-app", "electron" ], ... } ``` ]] .column_t1[.vmiddle[ ``` ... * "dependencies": { * "electron-debug": "^0.5.0" }, * "devDependencies": { * "electron-packager": "^5.0.0", * "electron-prebuilt": "^0.36.0", "xo": "^0.12.0" }, "xo": { "esnext": true, "envs": [ "node", "browser" ] } ``` ]] --- class: split-50 nopadding .column_t1[.vmiddle[ # index.js ]] .column_t2[.vmiddle[ ``` 'use strict'; const electron = require('electron'); const app = electron.app; //------------------------------- require('crash-reporter').start(); require('electron-debug')(); //------------------------------- let mainWindow; //------------------------------- function onClosed() { mainWindow = null; } //------------------------------- function createMainWindow() { const win = new electron.BrowserWindow({ width: 800, height: 600 }); win.loadURL(`file://${__dirname}/index.html`); win.on('closed', onClosed); return win; } //------------------------------- *app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); } }); //------------------------------- *app.on('activate', () => { if (!mainWindow) { mainWindow = createMainWindow(); } }); //------------------------------- *app.on('ready', () => { mainWindow = createMainWindow(); }); ``` ]] --- class: split-30 nopadding background-image: url(https://cloud.githubusercontent.com/assets/4231611/11023040/67004252-86a0-11e5-88cb-87a74f7912e4.jpg) .column_t2.center[.vmiddle[ .fgtransparent[ #
] ]] .column_t2[.vmiddle.nopadding[ .shadelight[.boxtitle1[ # Angular.JS Todo @ Electron ### ]] ]] --- class: column_t1 middle .figstyle1[ ![](images/fig03.jpg) ] .center[] --- class: column_t1 middle .figstyle1[ ![](images/fig04.jpg) ] .center[] --- class: split-50 nopadding .column_t2[.vmiddle[ ``` { "name": "app-03", "version": "1.0.0", "description": "A minimal Electron application", * "main": "main.js", "devDependencies": { "electron-prebuilt": "^0.36.0" }, * "dependencies": { * "lowdb": "^0.11.2" } } ``` .center[package.json] ]] .column_t1[.vmiddle[ ``` 'use strict'; const electron = require('electron'); const app = electron.app; const BrowserWindow = electron.BrowserWindow; //-------------------------------------- let mainWindow; //-------------------------------------- *app.on('window-all-closed', function() { if (process.platform != 'darwin') { app.quit(); } }); //-------------------------------------- *app.on('ready', function() { mainWindow = new BrowserWindow({width: 800, height: 600}); mainWindow.loadURL('file://' + __dirname + '/angular-offline-todo.html'); * mainWindow.setMenu(null); mainWindow.on('closed', function() { mainWindow = null; }); }); ``` .center[main.js] ]] --- class: split-50 nopadding .column_t1[.vmiddle[ ``` (function () { 'use strict'; * angular.module('todoApp', []) * .controller('todoListController', [TodoListController]); function TodoListController() { var todoList = this; * todoList.todos = []; * var low = require('lowdb'); * var storage = require('lowdb/file-sync'); * todoList.db = low('app-03/db.json', { storage }); * getAllTodos(); * todoList.addTodo = function() { * var varid = todoList.db('todos').size(); * while(todoList.db('todos').find({ id: varid })) { varid += 1; } * var data = { id: varid, text: todoList.todoText, done:false}; * todoList.db('todos').push(data); * todoList.todos.push(data); todoList.todoText = ''; }; todoList.remaining = function() { var count = 0; angular.forEach(todoList.todos, function(todo) { count += todo.done ? 0 : 1; }); return count; }; ``` ]] .column_t2[.vmiddle[ ### angular-offline-todo.js ``` todoList.archive = function() { var oldTodos = todoList.todos; todoList.todos = []; angular.forEach(oldTodos, function(todo) { if (!todo.done) todoList.todos.push(todo); }); }; * todoList.updDone = function(idx){ * var data = todoList.db('todos') * .chain() * .find({ id: todoList.todos[idx].id }) * .assign({ done: todoList.todos[idx].done}) * .value(); }; * function getAllTodos() { * todoList.todos = todoList.db('todos').cloneDeep(); }; } })(); ``` ]] --- class: split-50 nopadding .column_t2[.vmiddle[ ```html
Todo
*
{{todoList.remaining()}} of {{todoList.todos.length}} remaining
[
archive
]
*
*
{{todo.text}}
``` ]] .column_t1[.vmiddle[ ## angular-offline-todo.html ]] --- class: split-30 nopadding background-image: url(https://cloud.githubusercontent.com/assets/4231611/11023040/67004252-86a0-11e5-88cb-87a74f7912e4.jpg) .column_t2.center[.vmiddle[ .fgtransparent[ #
] ]] .column_t2[.vmiddle.nopadding[ .shadelight[.boxtitle1[ # Electron + Photon ### ]] ]] --- class: column_t1 middle .figstyle1[ ![](images/fig05.jpg) ] .center[] --- class: split-50 nopadding .column_t2[.vmiddle[ ## Photon Template App ``` { "name": "proton-template-app", "version": "1.0.0", "description": "A simple template app for Proton", * "main": "app.js", "author": "Connor Sears", "scripts": { "start": "electron ." } } ``` .center[package.json] ]] .column_t1[.vmiddle[ ``` var app = require('app'); var BrowserWindow = require('browser-window'); //------------------------------------- var mainWindow = null; //------------------------------------- *app.on('window-all-closed', function() { if (process.platform != 'darwin') { app.quit(); } }); //------------------------------------- *app.on('ready', function() { mainWindow = new BrowserWindow({ width: 800, height: 600, 'min-width': 480, 'min-height': 360, 'accept-first-mouse': true, 'title-bar-style': 'hidden' }); mainWindow.loadURL('file://' + __dirname + '/index.html'); mainWindow.setMenu(null); mainWindow.on('closed', function() { mainWindow = null; }); }); ``` .center[app.js] ]] --- class: split-50 nopadding .column_t1[.vmiddle[ ## Photon Template App ### .bluelight[package.json + app.js] ### .bluelight[index.html + js/menu.js] ]] .column_t2[.vmiddle[ ``` var remote = require('remote') var Menu = remote.require('menu') var MenuItem = remote.require('menu-item') //--------------------------------- var menu = new Menu() *menu.append(new MenuItem({ label: 'Delete', click: function() { alert('Deleted') } })); //--------------------------------- *menu.append(new MenuItem({ label: 'More Info...', click: function() { alert('Here is more information') } })); //--------------------------------- *window.addEventListener('contextmenu', function (e) { * e.preventDefault(); * menu.popup(remote.getCurrentWindow()); *}, false); ``` .center[js/menu.js] ]] --- class: split-50 nopadding .column_t2[.vmiddle[ ## index.html ```
Photon
*
*
Photon
*
*
*
... *
*
*
``` ]] .column_t1[.vmiddle[ ```html *
*
Favorites
connors
Photon
Downloads
Documents
Applications
AirDrop
Desktop
*
*
*
*
Name
Kind
Date Modified
Author
bars.scss
Document
Oct 13, 2015
connors
...
base.scss
Document
Oct 13, 2015
connors
*
*
``` ]] --- class: split-30 nopadding background-image: url(https://cloud.githubusercontent.com/assets/4231611/11023040/67004252-86a0-11e5-88cb-87a74f7912e4.jpg) .column_t2.center[.vmiddle[ .fgtransparent[ #
] ]] .column_t2[.vmiddle.nopadding[ .shadelight[.boxtitle1[ # Photon Angular Todo-App ### ]] ]] --- class: column_t1 middle .figstyle1[ ![](images/fig06.jpg) ] .center[] --- class: split-50 nopadding .column_t2[.vmiddle[ ``` # app.js *mainWindow.loadURL('file://' + __dirname + '/angular-offline-todo.html'); # angular-offline-todo.js *todoList.db = low('app-05/app/db.json', { storage }); ``` ```css # angular-offline-todo.css *.margin10 { margin: 10px; width: inherit !important; } ``` ]] .column_t1[.vmiddle[ # Minor Changes ### .bluelight[app.js] ### .bluelight[angular-offline-todo.js] ### .bluelight[angular-offline-todo.css] ]] --- class: split-50 nopadding .column_t1[.vmiddle[ ### angular-offline-todo.html ```html
*
*
Photon Angular Todo.App
*
* ... *
``` ]] .column_t2[.vmiddle[ ```html *
*
DONE
Todo
{{todo.text}}
*
*
* ``` ]] --- # References 1. [Electron](http://electron.atom.io/) 1. [sindresorhus/awesome-electron](https://github.com/sindresorhus/awesome-electron) 1. [Photon ยท Components](http://photonkit.com/components/) --- class: split-30 nopadding background-image: url(https://cloud.githubusercontent.com/assets/4231611/11023040/67004252-86a0-11e5-88cb-87a74f7912e4.jpg) .column_t2.center[.vmiddle[ .fgtransparent[ #
] ]] .column_t2[.vmiddle.nopadding[ .shadelight[.boxtitle1[ # END ### [Eueung Mulyana](https://github.com/eueung) ### http://eueung.github.io/js/electron #### JS CodeLabs | [Attribution-ShareAlike CC BY-SA](https://creativecommons.org/licenses/by-sa/4.0/) #### ]] ]]