Last active
September 25, 2016 21:00
-
-
Save peaBerberian/a5f309288e8e4371655b39ea6007a70c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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