├── .buildconfig ├── .gitignore ├── LICENSE ├── README.md ├── debug.js ├── lib └── main.dart ├── package.json ├── pubspec.yaml ├── screenshots └── main.png └── web ├── assets └── FontManifest.json ├── favicon.png ├── icons ├── Icon-192.png └── Icon-512.png ├── index.html ├── main.dart ├── main.js ├── manifest.json ├── package.json └── preload.js /.buildconfig: -------------------------------------------------------------------------------- 1 | [default] 2 | name=Default 3 | runtime=host 4 | config-opts= 5 | run-opts= 6 | prefix=/home/nmcain/.cache/gnome-builder/install/assets/host 7 | app-id= 8 | postbuild= 9 | prebuild= 10 | default=true 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | # Files and directories created by pub 3 | .dart_tool/ 4 | .vscode/ 5 | .packages 6 | # Remove the following pattern if you wish to check in your lock file 7 | pubspec.lock 8 | 9 | # Conventional directory for build outputs 10 | build/ 11 | 12 | # Directory created by dartdoc 13 | doc/api/ 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 HAYDER 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # electron-quick-start-flutter 2 | A minimal Electron application with flutter & dart 3 | 4 | ![Screenshot](screenshots/main.png) 5 | 6 | ## To Use 7 | 8 | ```bash 9 | # Clone this repository 10 | git clone https://github.com/hayderux/electron-flutter 11 | # Go into the repository 12 | cd electron-flutter 13 | #install flutter dependencies 14 | flutter pub get 15 | # Install dependencies 16 | npm install 17 | # Run the app 18 | npm run dev 19 | ``` 20 | 21 | 22 | 23 | 24 | ## Release 25 | To build for production, first run `npm run build`. 26 | 27 | The output directory, `build` contains a `package.json` pointing to the built 28 | application, and can be run as follows: 29 | 30 | ```bash 31 | cd build 32 | npm install 33 | npm start 34 | ``` 35 | ## Package 36 | The output directory's package manifest, build/package.json, includes electron-packager, and therefore can be packaged for distribution on Windows, MacOS, and Linux. 37 | 38 | to build for the host platform run: 39 | ``` 40 | npm run build 41 | ``` 42 | To build for all platforms, run : 43 | 44 | ``` 45 | npm run package 46 | ``` 47 | -------------------------------------------------------------------------------- /debug.js: -------------------------------------------------------------------------------- 1 | // Modules to control application life and create native browser window 2 | const { app, BrowserWindow } = require('electron') 3 | const path = require('path') 4 | 5 | // Keep a global reference of the window object, if you don't, the window will 6 | // be closed automatically when the JavaScript object is garbage collected. 7 | let mainWindow 8 | 9 | function createWindow() { 10 | // Create the browser window. 11 | mainWindow = new BrowserWindow({ 12 | width: 800, 13 | height: 600, 14 | webPreferences: { 15 | preload: path.join(__dirname, 'preload.js') 16 | } 17 | }) 18 | 19 | // and load the index.html of the app. 20 | mainWindow.loadURL("http://localhost:8096") 21 | 22 | // Open the DevTools. 23 | // mainWindow.webContents.openDevTools() 24 | 25 | // Emitted when the window is closed. 26 | mainWindow.on('closed', function () { 27 | // Dereference the window object, usually you would store windows 28 | // in an array if your app supports multi windows, this is the time 29 | // when you should delete the corresponding element. 30 | mainWindow = null 31 | }) 32 | } 33 | 34 | // This method will be called when Electron has finished 35 | // initialization and is ready to create browser windows. 36 | // Some APIs can only be used after this event occurs. 37 | app.on('ready', createWindow) 38 | 39 | // Quit when all windows are closed. 40 | app.on('window-all-closed', function () { 41 | // On macOS it is common for applications and their menu bar 42 | // to stay active until the user quits explicitly with Cmd + Q 43 | if (process.platform !== 'darwin') app.quit() 44 | }) 45 | 46 | app.on('activate', function () { 47 | // On macOS it's common to re-create a window in the app when the 48 | // dock icon is clicked and there are no other windows open. 49 | if (mainWindow === null) createWindow() 50 | }) 51 | 52 | // In this file you can include the rest of your app's specific main process 53 | // code. You can also put them in separate files and require them here. 54 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | void main() => runApp(MyApp()); 4 | 5 | class MyApp extends StatelessWidget { 6 | // This widget is the root of your application. 7 | @override 8 | Widget build(BuildContext context) { 9 | return MaterialApp( 10 | title: 'Flutter Demo', 11 | theme: ThemeData( 12 | primarySwatch: Colors.blue, 13 | ), 14 | home: MyHomePage(title: 'Flutter Demo Home Page'), 15 | ); 16 | } 17 | } 18 | 19 | class MyHomePage extends StatelessWidget { 20 | MyHomePage({Key? key, this.title}) : super(key: key); 21 | 22 | final String? title; 23 | 24 | @override 25 | Widget build(BuildContext context) { 26 | // The Flutter framework has been optimized to make rerunning build methods 27 | // fast, so that you can just rebuild anything that needs updating rather 28 | // than having to individually change instances of widgets. 29 | return Scaffold( 30 | floatingActionButton: FloatingActionButton( 31 | child: Icon(Icons.add), 32 | onPressed: () {}, 33 | ), 34 | body: Center( 35 | // Center is a layout widget. It takes a single child and positions it 36 | // in the middle of the parent. 37 | child: Column( 38 | // Column is also layout widget. It takes a list of children and 39 | // arranges them vertically. By default, it sizes itself to fit its 40 | // children horizontally, and tries to be as tall as its parent. 41 | // 42 | // Invoke "debug painting" (choose the "Toggle Debug Paint" action 43 | // from the Flutter Inspector in Android Studio, or the "Toggle Debug 44 | // Paint" command in Visual Studio Code) to see the wireframe for each 45 | // widget. 46 | // 47 | // Column has various properties to control how it sizes itself and 48 | // how it positions its children. Here we use mainAxisAlignment to 49 | // center the children vertically; the main axis here is the vertical 50 | // axis because Columns are vertical (the cross axis would be 51 | // horizontal). 52 | mainAxisAlignment: MainAxisAlignment.center, 53 | children: [ 54 | Text( 55 | 'Hello, World!', 56 | style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold), 57 | ), 58 | ], 59 | ), 60 | ), // This trailing comma makes auto-formatting nicer for build methods. 61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-quick-start-flutter", 3 | "version": "1.0.0", 4 | "description": "A minimal Electron application with flutter & dart", 5 | "main": "debug.js", 6 | "scripts": { 7 | "clean": "flutter clean", 8 | "build": "flutter build web", 9 | "build_flutter_server": "flutter run --web-port 8096 -d web-server", 10 | "dev": "run-p \"build_flutter_server\" \"start\"", 11 | "start": "electron ." 12 | }, 13 | "repository": "https://github.com/electron/electron-quick-start", 14 | "author": "GitHub", 15 | "license": "MIT", 16 | "devDependencies": { 17 | "electron": "^11.1.0", 18 | "npm-run-all": "^4.1.5" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: hello_world 2 | description: An app built using Flutter for web 3 | 4 | environment: 5 | sdk: '>=2.12.0 <3.0.0' 6 | 7 | dependencies: 8 | flutter: 9 | sdk: flutter 10 | 11 | flutter: 12 | uses-material-design: true 13 | -------------------------------------------------------------------------------- /screenshots/main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayderux/electron-flutter/4472a9d1f6c747eab95d2b2999e9a9bc8807450f/screenshots/main.png -------------------------------------------------------------------------------- /web/assets/FontManifest.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "family": "MaterialIcons", 4 | "fonts": [ 5 | { 6 | "asset": "https://fonts.gstatic.com/s/materialicons/v42/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2" 7 | } 8 | ] 9 | }, 10 | { 11 | "family": "GoogleSans", 12 | "fonts": [ 13 | { 14 | "asset": "GoogleSans-Regular.ttf" 15 | } 16 | ] 17 | }, 18 | { 19 | "family": "GalleryIcons", 20 | "fonts": [ 21 | { 22 | "asset": "GalleryIcons.ttf" 23 | } 24 | ] 25 | }, 26 | { 27 | "family": "AbrilFatface", 28 | "fonts": [ 29 | { 30 | "asset": "AbrilFatface-Regular.ttf" 31 | } 32 | ] 33 | }, 34 | { 35 | "family": "LibreFranklin", 36 | "fonts": [ 37 | { 38 | "asset": "LibreFranklin-Regular.ttf" 39 | } 40 | ] 41 | }, 42 | { 43 | "family": "Merriweather", 44 | "fonts": [ 45 | { 46 | "asset": "Merriweather-Regular.ttf" 47 | } 48 | ] 49 | }, 50 | { 51 | "family": "Raleway", 52 | "fonts": [ 53 | { 54 | "asset": "Raleway-Regular.ttf" 55 | } 56 | ] 57 | } 58 | ] 59 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayderux/electron-flutter/4472a9d1f6c747eab95d2b2999e9a9bc8807450f/web/favicon.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayderux/electron-flutter/4472a9d1f6c747eab95d2b2999e9a9bc8807450f/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hayderux/electron-flutter/4472a9d1f6c747eab95d2b2999e9a9bc8807450f/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Flutter Demo 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /web/main.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | import 'package:hello_world/main.dart' as app; 5 | 6 | main() async { 7 | app.main(); 8 | } 9 | -------------------------------------------------------------------------------- /web/main.js: -------------------------------------------------------------------------------- 1 | // Modules to control application life and create native browser window 2 | const { app, BrowserWindow } = require('electron') 3 | const path = require('path') 4 | 5 | // Keep a global reference of the window object, if you don't, the window will 6 | // be closed automatically when the JavaScript object is garbage collected. 7 | let mainWindow 8 | 9 | function createWindow() { 10 | // Create the browser window. 11 | mainWindow = new BrowserWindow({ 12 | width: 800, 13 | height: 600, 14 | webPreferences: { 15 | preload: path.join(__dirname, 'preload.js') 16 | } 17 | }) 18 | 19 | // and load the index.html of the app. 20 | mainWindow.loadFile('index.html') 21 | 22 | // Open the DevTools. 23 | // mainWindow.webContents.openDevTools() 24 | 25 | // Emitted when the window is closed. 26 | mainWindow.on('closed', function () { 27 | // Dereference the window object, usually you would store windows 28 | // in an array if your app supports multi windows, this is the time 29 | // when you should delete the corresponding element. 30 | mainWindow = null 31 | }) 32 | } 33 | 34 | // This method will be called when Electron has finished 35 | // initialization and is ready to create browser windows. 36 | // Some APIs can only be used after this event occurs. 37 | app.on('ready', createWindow) 38 | 39 | // Quit when all windows are closed. 40 | app.on('window-all-closed', function () { 41 | // On macOS it is common for applications and their menu bar 42 | // to stay active until the user quits explicitly with Cmd + Q 43 | if (process.platform !== 'darwin') app.quit() 44 | }) 45 | 46 | app.on('activate', function () { 47 | // On macOS it's common to re-create a window in the app when the 48 | // dock icon is clicked and there are no other windows open. 49 | if (mainWindow === null) createWindow() 50 | }) 51 | 52 | // In this file you can include the rest of your app's specific main process 53 | // code. You can also put them in separate files and require them here. 54 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "xps", 3 | "short_name": "xps", 4 | "start_url": ".", 5 | "display": "minimal-ui", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "productName": "Flutter App", 4 | "description": "", 5 | "version": "1.0.0", 6 | "main": "main.js", 7 | "scripts": { 8 | "build": "electron-packager .", 9 | "package": "electron-packager . --all", 10 | "start": "electron ." 11 | }, 12 | "devDependencies": { 13 | "electron": "^13.1.7", 14 | "electron-packager": "^15.3.0" 15 | } 16 | } -------------------------------------------------------------------------------- /web/preload.js: -------------------------------------------------------------------------------- 1 | // All of the Node.js APIs are available in the preload process. 2 | // It has the same sandbox as a Chrome extension. 3 | window.addEventListener('DOMContentLoaded', () => { 4 | const replaceText = (selector, text) => { 5 | const element = document.getElementById(selector) 6 | if (element) element.innerText = text 7 | } 8 | 9 | for (const type of ['chrome', 'node', 'electron']) { 10 | replaceText(`${type}-version`, process.versions[type]) 11 | } 12 | }) 13 | --------------------------------------------------------------------------------