Skip to content

Commit

Permalink
nw-splasher
Browse files Browse the repository at this point in the history
  • Loading branch information
TheJaredWilcurt committed Sep 20, 2019
1 parent e524b69 commit 0779b75
Show file tree
Hide file tree
Showing 4 changed files with 257 additions and 1 deletion.
51 changes: 50 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,51 @@
# nw-splasher
# NW-Splasher

Small library to show a splash screen until main application loads.

The splash screen will run in a separate process so any animations will play smoothly while the app is loading.


* * *


## Demo

Here is a demo projec that uses the `nw-splasher.js` and `nw-splasher.css` files:

* https://github.com/nwutils/nw-splash-screen-example


* * *


## Usage

1. `npm install --save nw-splasher`
1. Create a `splash.html` file and an `index.html` file (for your app)
* Add this line to the `<head>` of both files.
* `<script src="node_modules/nw-splasher/nw-splasher.js"></script>`
1. In `package.json` set `"main": "splash.html"`
1. In the `splash.html` run `nwSplasher.loadAppWindowInBackground()`
1. In the `index.html` run `nwSplasher.closeSplashAndShowApp()` after the app is done loading and ready to be displayed


## API

`nwSplasher.loadAppWindowInBackground(url, newWindowOptions, port)`

Used by your Splash screen window. This creates a websocket and spawns your main app in a hidden window. Then waits for the app to send a signal to the websocket to close the splash screen.

Argument | Optional | Type | Description | Defaults
:-- | :-- | :-- | :-- | :--
`url` | yes | String | URL to load in the App window. | Defaults to `index.html`, `default.html`, `main.html`, or `app.html` if those files exist, or the first html file it finds in the current directory. Console logs if no html file found.
`newWindowOptions` | yes | Object | Object with the [NW.js Window Subfields](http://docs.nwjs.io/en/latest/References/Manifest%20Format/#window-subfields). | `show` is always set to `false`. `new_instance` is always set to `true`.
`port` | yes | Number | If you pass in a number it must match the same port number passed in the app window. | Defaults to 4443.


`nwSplasher.closeSplashAndShowApp(port)`

Call this from your App window when it is ready to be shown. This will also trigger closing the Splash screen window.

Argument | Optional | Type | Description | Defaults
:-- | :-- | :-- | :-- | :--
`port` | yes | Number | If you pass in a number it must match the same port number passed in the splash window. | Defaults to 4443.
61 changes: 61 additions & 0 deletions nw-splasher.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
html,
body,
.wrapper {
height: 100%;
box-sizing: border-box;
}

body {
background: transparent;
border: 4px solid #222;
border-radius: 20px;
margin: 0px;
padding: 00px;
color: #DEDEDE;
font-family: sans-serif;
text-align: center;
}

.wrapper {
background: linear-gradient(300deg, hsla(0, 0%, 18%, 1), hsla(0, 0%, 22%, 0.3));
border-radius: 10px;
padding: 20px;
}

.drag-enable {
-webkit-app-region: drag;
}

.drag-disable {
-webkit-app-region: no-drag;
}

.close {
position: absolute;
top: 3px;
right: 12px;
font-size: 30px;
cursor: pointer;
}

@keyframes spin {
0% {
transform: rotateZ(0deg);
}
45% {
background-color: rgba(168, 225, 136, 0.95)
}
100% {
transform: rotateZ(719deg);
}
}

.spinner {
display: block;
width: 100px;
height: 100px;
background: rgba(168, 180, 136, 0.95);
border-radius: 10px;
margin: 50px auto;
animation: spin 4s ease 0s infinite normal;
}
125 changes: 125 additions & 0 deletions nw-splasher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
const nwSplasher = {
º: '%c',
consoleNormal: 'font-family: sans-serif',
consoleBold: '' +
'font-family: sans-serif' +
'font-weight: bold',
consoleCode: '' +
'background: #EEEEF6;' +
'border: 1px solid #B2B0C1;' +
'border-radius: 7px;' +
'padding: 2px 8px 3px;' +
'color: #5F5F5F;' +
'line-height: 22px;' +
'box-shadow: 0px 0px 1px 1px rgba(178,176,193,0.3)',
validateUrl: function (url) {
if (typeof(url) === 'string') {
return url;
}
let fs = require('fs');
files = fs.readdirSync('.');
files = files.filter(function (file) {
return file.endsWith('.html')
});

if (files.length) {
url = files[0];
}

const defaults = [
'app.html',
'main.html',
'default.html',
'index.html',
];

defaults.forEach(function (possibleFile) {
if (files.includes(possibleFile)) {
url = possibleFile;
}
});
if (url) {
return url;
}
return false;
},
validateNewWindowOptions: function (newWindowOptions) {
if (!newWindowOptions || typeof(newWindowOptions) !== 'object' || Array.isArray(newWindowOptions)) {
newWindowOptions = {};
}

// Needs to be a new instance so splash screen animations play smoothly
newWindowOptions.new_instance = true;
// hide the app window until it signals it is done loading
newWindowOptions.show = false;

return newWindowOptions;
},
validatePort: function (port) {
if (typeof(port) !== 'number') {
port = 4443;
}
return port;
},
/**
* Used by your Splash screen window. This creates a websocket and spawns
* your main app in a hidden window. Then waits for the app to send a signal
* to the websocket to close the splash screen.
*
* All params are optional.
*
* @param {string} url URL to load in the App window. Defaults to index.html, default.html, main.html, or app.html if those files exist, or the first html file it finds.
* @param {object} newWindowOptions Object with the NW.js Window fields (height, width, frameless, etc)
* @param {number} port Defaults to 1337, must match the same port number used in the app window
* @return {undefined} Returns nothing, just executes
*/
loadAppWindowInBackground: function (url, newWindowOptions, port) {
url = this.validateUrl(url);
newWindowOptions = this.validateNewWindowOptions(newWindowOptions);
port = this.validatePort(port);

if (!url) {
console.log(this.º + 'NW-Splasher: Could not find a valid path to load your app window.\n' +
'Pass in url or filename to load in the app Window.', this.consoleNormal);
console.log(this.º + 'Example:', this.consoleBold);
console.log(this.º + 'nwSplasher.loadAppInBackground(\'index.html\');', this.consoleCode);
return;
}

const net = require('net');
const server = net.createServer(function (socket) {
socket.write('Echo server');
socket.pipe(socket);

// Handle incoming messages app window
socket.on('data', function (data) {
if (data.toString() === 'loaded') {
server.close();
nw.Window.get().close(true);
}
});
});

server.listen(port, 'localhost');

// Launch hidden app window and wait for it to signal to close the splasher window
nw.Window.open(url, newWindowOptions);
},
/**
* Call this from your App window when it is ready to be shown.
* This will also trigger closing the Splash screen window.
*
* @param {number} port Optional port number, defaults to 1337. Must match port number used in Splash window
* @return {undefined} Nothing is returned, this just runs a command.
*/
closeSplashAndShowApp: function (port) {
port = this.validatePort(port);

const net = require('net');
const client = new net.Socket();
client.connect(port, 'localhost');

client.write('loaded');
nw.Window.get().show();
}
};
21 changes: 21 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "nw-splasher",
"version": "1.0.0",
"description": "Small library to show a splash screen until main application loads.",
"main": "nw-splasher.js",
"repository": {
"type": "git",
"url": "git+https://github.com/nwutils/nw-splasher.git"
},
"keywords": [
"NW.js",
"Splash screen",
"loading"
],
"author": "",
"license": "MIT",
"bugs": {
"url": "https://github.com/nwutils/nw-splasher/issues"
},
"homepage": "https://github.com/nwutils/nw-splasher#readme"
}

0 comments on commit 0779b75

Please sign in to comment.