Skip to content

Instantly share code, notes, and snippets.

@peaBerberian
Last active September 25, 2016 21:00
Show Gist options
  • Save peaBerberian/a5f309288e8e4371655b39ea6007a70c to your computer and use it in GitHub Desktop.
Save peaBerberian/a5f309288e8e4371655b39ea6007a70c to your computer and use it in GitHub Desktop.
/**
* MW:
* 1. Provides a generic API (can be adapted to other platform) for low-level
* calls.
* 2. Platform-dependent.
* 3. Mostly stateless.
* 4. Uses RxJS observables because of heavy event handling (STB events,
* multiple requests).
*
* Core (Well, only the Modules/Dispatcher part):
* 1. Directly uses the MW functions.
* 2. Stores the up-to-date data of the STB in its __state__.
* All of it is accessible synchronously.
* 3. Cross-platform
* 4. Provides __actions__ to the other part of our application, which will
* update the state accordingly
* 5. Provides __selectors__ to parse an intricate state (array,
* subproperties, values that may depend on the config...)
* 6. Uses RxJS observables because of heavy event handling (MW functions).
* 7. Gives access to actions and its state via a 'dispatcher'.
*
* Boot:
* 1. Exploits directly the core state and actions.
* 2. Runs routines on boot.
* 3. Performs checks on the initial state of our application (deactivate an
* initially active wifi scan...)
* 4. Automatically performs operations during the runtime of our
* application on events (renew certificate...)
* 5. Launch the regular UI/Primo...
* 6. Uses RxJS observables because of heavy event handling (using state
* updates which can be seen as a stream).
*
* NOTE: In the _core_ term, we generally agglomerate MW+Core+Boot, the "low
* level" part in contrast with the UI.
*
* Parsers (A new one? Would initially be put in the UI):
* 1. Exploits directly the core (Modules) state and actions.
* 2. Provides functions to hide the techical complexity of frequent usecases.
* 3. Might perform ajax request directly.
* 4. Often makes use of promises to easily interact with the UI:
* > a UI action worked and may return a result.
* > a UI action failed and may return an error.
*
* UI:
* 1. Uses parsers / the dispatcher to interact with the outside world.
* 2. Uses Redux and React for UI-only state handling.
*/
// parsers/network.js
/**
* This file 'parse' the network state and execute actions to provide
* functions corresponding to real usecases to the UI.
*/
import dispatcher from '../core/dispatcher';
// frequently used methods
const {
dispatch,
$get,
get
} = dispatcher;
// asynchronous functions return Promises
const startScanningWifi = () : Promise => {
dispatch({ type: 'NETWORK:START_SCAN' });
return new Promise((res, rej) => {
Observable.merge(
$get('NETWORK.scanActive')
.filter(e => !!e),
$get('NETWORK.error')
.filter(e => e.action === 'START_SCAN')
).take(1)
.subscribe(function (res) {
if(res.err) {
rej(res.err);
} else {
res();
}
};
});
});
};
const getWifiScanResults = () : Promise => {
dispatch({ type: 'NETWORK:FETCH_SCAN_RESULTS' });
return new Promise((res, rej) => {
$get('NETWORK.resultsFetchStatus').subscribe(function (status) {
switch (status) {
case 'fetched':
this.unsubscribe();
res(get('NETWORK.scanResults'));
break;
case 'failed':
this.unsubscribe();
rej(get('NETWORK.error.err'))
};
});
});
};
// more complex usecase
const connectToWifi = (config) : promise => {
dispatch({
type: 'NETWORK:CONNECT',
payload: {
type: 'wifi',
config
}
});
return new Promise((res, rej) => {
let triedConnecting = false;
$get('NETWORK:wifiInterface.connectivity')
.subscribe((con) => {
switch (con) {
// NOTE: This is dangerous as it expects a 'connecting'
// connectivity to be always sent. Add state pending to
// connectivity?
case 'connecting':
triedConnecting = true;
break;
case 'connected':
// this is also dangerous as we would be instantly resolved if we
// were connected on a network with the same ssid.
// Add state pending to connectivity?
const essid = get('NETWORK:wifiInterface.wifiConfiguration.essid');
if (essid = config.essid) {
res();
}
break;
case 'failed':
if (triedConnecting) {
rej();
}
break;
}
});
});
};
export {
startScanningWifi,
getWifiScanResults
};
// ui/wifiScan.js
// importing parsers.
import { startScanningWifi, getWifiScanResults } from '../parsers/network.js';
// using the dispatcher directly
import dispatcher from '../core/dispatcher';
dispatcher.$get('NETWORK:ethernetInterface.connectivity')
.subscribe((c) => {
if (c === 'connected') {
// directly show that we are connected via ethernet
} else {
// hide if we are not connected via ethernet
}
});
try {
await startScanningWifi();
const results = await getWifiScanResults();
// display results
} catch (e) {
// displaying something on error?
}
// ui/connectWifi.js
import { connectToWifi } from '../parsers/network.js';
try {
// connect to open network toto
await connectToWifi({
essid: 'toto'
});
// it works!! We are now on toto
} catch(e) {
// it failed!
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment