aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--package.json1
-rw-r--r--src/index.html167
-rw-r--r--src/index.js49
-rw-r--r--src/js/app.js28
-rw-r--r--src/js/bluetooth.js147
-rw-r--r--src/js/templates.js19
-rw-r--r--src/styles/app.scss11
-rw-r--r--src/styles/landscape.scss14
-rw-r--r--src/styles/main.scss165
-rw-r--r--src/styles/portrait.scss6
-rw-r--r--src/templates/bluetooth.template.html52
-rw-r--r--src/templates/main.template.html73
-rw-r--r--webpack.config.js5
13 files changed, 285 insertions, 452 deletions
diff --git a/package.json b/package.json
index 6fd6ffa..8fbb47e 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,7 @@
},
"dependencies": {
"mustache": "^3.1.0",
+ "bootstrap": "4.4.1",
"agl-js-api": "https://github.com/AGL-web-applications/agl-js-api.git#master"
}
}
diff --git a/src/index.html b/src/index.html
index 20de554..7bd906b 100644
--- a/src/index.html
+++ b/src/index.html
@@ -21,171 +21,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
- <div class="page" id="main">
- <h1 class="header">
- Settings
- </h1>
- <div class="container">
- <a href="#" class="entry" onclick="window.show('datetime');">
- <div class="icon">
- <i class="fa fa-clock"></i>
- </div>
- <div class="label">
- Date & Time
- </div>
- <div class="control">
- </div>
- </a>
- <a href="#" class="entry">
- <div class="icon">
- <i class="fab fa-bluetooth-b"></i>
- </div>
- <div class="label" onclick="window.show('bluetooth');">
- Bluetooth
- </div>
- <div id="BluetoothControl" class="control enabled" onclick="window.toggle_bluetooth();">
- <span class="fa fa-toggle-on on"></span>
- <span class="fa fa-toggle-off off"></span>
- </div>
- </a>
- <a href="#" class="entry" onclick="window.show('wifi');">
- <div class="icon">
- <i class="fas fa-wifi"></i>
- </div>
- <div class="label">
- Wifi
- </div>
- <div class="control">
- <!-- <span class="fa fa-toggle-on on"></span> -->
- <span class="fa fa-toggle-off off"></span>
- </div>
- </a>
- <a href="#" class="entry" onclick="window.show('wired');">
- <div class="icon">
- <i class="fas fa-network-wired"></i>
- </div>
- <div class="label">
- Wired
- </div>
- </a>
- <a href="#" class="entry" onclick="window.show('version');">
- <div class="icon"></div>
- <div class="icon">
- <i class="fas fa-tachometer-alt"></i>
- </div>
- <div class="label">
- Version info
- </div>
- </a>
- </div>
- </div>
-
- <div class="secondary page hide" id="datetime">
- <h1 class="header">
- <a href="#" class="backButton" onclick="window.hide('datetime')">
- <i class="fas fa-chevron-left"></i>
- </a>
- Date & Time
- </h1>
- <div class="entry">
- <h2>
- Date
- </h2>
- </div>
- <div class="entry">
- <h2>
- Time
- </h2>
- </div>
- </div>
-
- <div class="secondary page hide" id="bluetooth">
- <h1 class="header">
- <a href="#" class="backButton" onclick="window.hide('bluetooth')">
- <i class="fas fa-chevron-left"></i>
- </a>
- Bluetooth
- </h1>
- <div id="BluetoothContainer" class="container"></div>
- <div class="footer">
- <a href="#" filter="available" class="button active" onclick="window.setFilter_bluetooth(this)">
- Available
- </a>
- <a href="#" filter="paired" class="button" onclick="window.setFilter_bluetooth(this)">
- Paired
- </a>
- <a href="#" filter="connected" class="button" onclick="window.setFilter_bluetooth(this)">
- Connected
- </a>
- </div>
- <script id="bluetooth-device-template" type="x-tmpl-mustache">
- <div class="entry" deviceId="{{device}}">
- <div class="icon">
- <span class="fab fa-bluetooth"></span>
- </div>
- <div class="label" onclick="window.manage_bluetooth('{{device}}', {{properties.paired}}, {{ properties.connected }})">
- <div class="title">
- {{ properties.name }}
- </div>
- <div class="subtitle">
- {{ properties.address }}
- </div>
- </div>
- <div class="control" onclick="window.remove_device_bluetooth('{{device}}')">
- <span class="fa fa-trash"></span>
- </div>
- </div>
- </script>
- </div>
-
- <div class="secondary page hide" id="wifi">
- <h1 class="header">
- <a href="#" class="backButton" onclick="window.hide('wifi')">
- <i class="fas fa-chevron-left"></i>
- </a>
- Wifi
- </h1>
- <div id="WifiContainer" class="container"></div>
- <script id="wifi-device-template" type="x-tmpl-mustache">
- <div class="entry" service="{{service}}">
- <div class="icon">
- <span class="fas fa-wifi"></span>
- </div>
- <div class="label" onclick="window.manage_bluetooth('{{device}}', {{properties.paired}}, {{ properties.connected }})">
- <div class="title">
- {{ properties.name }}
- </div>
- <div class="subtitle">
- {{ properties.ethernet.address }}
- </div>
- </div>
- <div class="control">
- {{ properties.strength }}%
- </div>
- </div>
- </script>
- </div>
-
- <div class="secondary page hide" id="wired">
- <h1 class="header">
- <a href="#" class="backButton" onclick="window.hide('wired')">
- <i class="fas fa-chevron-left"></i>
- </a>
- Wired
- </h1>
- </div>
-
- <div class="secondary page hide" id="version">
- <h1 class="header">
- <a href="#" class="backButton" onclick="window.hide('version')">
- <i class="fas fa-chevron-left"></i>
- </a>
- Version info
- </h1>
- </div>
-
- <div class="log" id="log">
-
- </div>
+
</body>
</html> \ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 6080b75..00da226 100644
--- a/src/index.js
+++ b/src/index.js
@@ -15,51 +15,12 @@
*/
/* JS */
import { init } from './js/app';
-import { toggle as toggle_bluetooth,
- pair as pair_bluetooth,
- connect as connect_bluetooth,
- disconnect as disconnect_bluetooth,
- filter as setFilter_bluetooth,
- remove as remove_device_bluetooth
-} from './js/bluetooth';
+
+import { api } from 'agl-js-api';
+import * as bluetooth from './js/bluetooth';
/* CSS */
import './styles/app.scss';
-window.show = function(page){
- document.getElementById('main').classList.add('hide');
- document.getElementById(page).classList.remove('hide');
-}
-
-window.hide = function(page) {
- document.getElementById('main').classList.remove('hide');
- document.getElementById(page).classList.add('hide');
-}
-
-window.toggle_bluetooth = toggle_bluetooth;
-window.remove_device_bluetooth = remove_device_bluetooth;
-window.manage_remove_bluetooth = function(deviceId, isPaired, isConnected) {
- if ( !isConnected ) {
- remove_device_bluetooth(deviceId);
- } else if ( isConnected ) {
- disconnect_bluetooth(deviceId);
- }
-}
-window.manage_bluetooth = function(deviceId, isPaired, isConnected) {
- if ( !isPaired && !isConnected ) {
- pair_bluetooth(deviceId);
- } else if ( isPaired && !isConnected ) {
- connect_bluetooth(deviceId);
- }
-};
-window.setFilter_bluetooth = function(entry){
- setFilter_bluetooth(entry.getAttribute('filter'));
- var buttons = document.getElementById('bluetooth').getElementsByClassName('footer')[0].getElementsByClassName('button');
-
- for( var i = 0; i < buttons.length; i++ ) {
- buttons[i].classList.remove('active');
- }
-
- entry.classList.add('active');
-}
-init(); \ No newline at end of file
+api.init();
+init();
diff --git a/src/js/app.js b/src/js/app.js
index f95852d..458a5d4 100644
--- a/src/js/app.js
+++ b/src/js/app.js
@@ -1,12 +1,26 @@
-import { init as init_bluetooth } from './bluetooth';
+import * as bluetooth from './bluetooth';
import { init as init_wifi } from './wifi';
+import { load as load_template } from './templates';
+import Mustache from 'mustache';
-import { api } from 'agl-js-api';
+var template;
+var page = {
+ bluetooth: true,
+ wifi: false
+};
-export function init() {
- api.init();
- init_bluetooth();
- init_wifi();
+export function show() {
+ page.bluetooth = bluetooth.getState();
+ document.body.innerHTML = Mustache.render(template, page);
}
-window.api = api; \ No newline at end of file
+export function init() {
+ load_template('main.template.html').then(function(result) {
+ template = result;
+ Mustache.parse(template);
+ show();
+ bluetooth.init();
+ }, function(error) {
+ console.error('ERRROR loading main template', error);
+ });
+} \ No newline at end of file
diff --git a/src/js/bluetooth.js b/src/js/bluetooth.js
index 30c2d82..65fa340 100644
--- a/src/js/bluetooth.js
+++ b/src/js/bluetooth.js
@@ -1,37 +1,43 @@
import { bluetooth } from 'agl-js-api';
import Mustache from 'mustache';
-
-window.bluetooth = bluetooth;
+import { load as load_template } from './templates';
+import * as app from './app';
+import { getMaxListeners } from 'cluster';
var template;
-var filterBy = 'available';
+var page = {
+ devices: [],
+ filter: {
+ available: true,
+ paired: false,
+ connected: false
+ },
+ powered: false
+};
-function update_state(state) {
- var control = document.getElementById('BluetoothControl');
- if( state.powered ) {
- control.classList.add('enabled');
- } else {
- control.classList.remove('enabled');
- }
+function render(){
+ document.body.innerHTML = Mustache.render(template, page);
}
function update_devices(devices) {
- var deviceList = document.getElementById('BluetoothContainer');
- deviceList.innerHTML = '';
-
+ page.devices = [];
devices.forEach(function(device) {
- if ( filterBy === 'connected' && device.properties.connected ) {
- deviceList.innerHTML += Mustache.render(template, device);
- } else if ( filterBy === 'paired' &&
+ if ( page.filter.connected && device.properties.connected ) {
+ page.devices.push(device);
+ } else if ( page.filter.paired &&
device.properties.paired &&
!device.properties.connected ) {
- deviceList.innerHTML += Mustache.render(template, device);
- } else if ( filterBy === 'available' &
+ page.devices.push(device);
+ } else if ( page.filter.available &
!device.properties.connected &&
!device.properties.paired) {
- deviceList.innerHTML += Mustache.render(template, device);
+ page.devices.push(device);
}
});
+
+ console.log(page);
+
+ render();
}
function refresh_devices() {
@@ -40,61 +46,98 @@ function refresh_devices() {
});
}
+function pair(deviceId) {
+ bluetooth.pair(deviceId).then(function() {
+ refresh_devices();
+ });
+}
+
+function connect(deviceId) {
+ bluetooth.connect(deviceId).then(function() {
+ refresh_devices();
+ });
+}
+
+function disconnect(deviceId) {
+ bluetooth.disconnect(deviceId).then(function() {
+ refresh_devices();
+ });
+}
+
export function toggle() {
bluetooth.adapter_state().then(function(result) {
bluetooth.adapter_state({
powered: !result.powered
- }).then(update_state);
+ }).then(function(state) {
+ page.powered = state.powered;
+ });
});
}
export function init() {
- template = document.getElementById('bluetooth-device-template').innerHTML;
- Mustache.parse(template);
- bluetooth.adapter_state({
- discovery: true
- }).then(update_state);
- refresh_devices();
+ load_template('bluetooth.template.html').then(function(result) {
+ template = result;
+ Mustache.parse(template);
+ }, function(error) {
+ console.error('ERROR Loading bluetooth template', error);
+ });
- // This code has been commented to improve performance
- // bluetooth.on_device_changes(function(data) {
- // bluetooth.managed_objects().then(function(result){
- // update_devices(result.devices);
- // });
- // }).then(function(result) {
- // console.log('SUBSCRIBED TO DEVICE CHANGES');
- // });
+ bluetooth.adapter_state().then(function(state) {
+ page.powered = state.powered;
+ });
+}
+
+export function getState() {
+ return page.powered;
}
-export function filter(filter) {
- filterBy = filter;
+export function show() {
refresh_devices();
}
-export function getFilter() {
- return filterBy;
+export function hide() {
+ app.show();
}
-export function remove(deviceId) {
- bluetooth.remove_device(deviceId).then(function() {
- refresh_devices();
- });
+export function available() {
+ page.filter = {
+ available: true,
+ paired: false,
+ connected: false
+ };
+ refresh_devices();
}
-export function pair(deviceId) {
- bluetooth.pair(deviceId).then(function() {
- refresh_devices();
- });
+export function connected() {
+ page.filter = {
+ available: false,
+ paired: false,
+ connected: true
+ };
+ refresh_devices();
}
-export function connect(deviceId) {
- bluetooth.connect(deviceId).then(function() {
- refresh_devices();
- });
+export function paired() {
+ page.filter = {
+ available: false,
+ paired: true,
+ connected: false
+ };
+ refresh_devices();
}
-export function disconnect(deviceId) {
- bluetooth.disconnect(deviceId).then(function() {
+export function remove(deviceId) {
+ bluetooth.remove_device(deviceId).then(function() {
refresh_devices();
});
+}
+
+export function manage(deviceId, paired, connected) {
+ if ( connected ) {
+ connect(deviceId);
+ } else if ( paired ) {
+ disconnect(deviceId);
+ } else {
+ pair(deviceId);
+ }
} \ No newline at end of file
diff --git a/src/js/templates.js b/src/js/templates.js
new file mode 100644
index 0000000..2513722
--- /dev/null
+++ b/src/js/templates.js
@@ -0,0 +1,19 @@
+export function load(template) {
+ return new Promise(function(resolve, reject){
+ var xhr = new XMLHttpRequest();
+
+ xhr.open('GET', '/templates/'+template);
+
+ xhr.send();
+
+ xhr.onload = function() {
+ if (xhr.status != 200) {
+ console.error('Error loading template', xhr.status, xhr.statusText);
+ reject(xhr.status);
+ } else {
+ console.log(xhr.responseType);
+ resolve(xhr.responseText);
+ }
+ };
+ });
+} \ No newline at end of file
diff --git a/src/styles/app.scss b/src/styles/app.scss
index c69ad19..d7290f4 100644
--- a/src/styles/app.scss
+++ b/src/styles/app.scss
@@ -5,8 +5,15 @@ $colors: (
grey: #848286
);
-@import "style.css";
+
+$body-bg: transparent;
+$body-color: #FFFFFF;
+$list-group-bg: transparent;
+$font-size-base: 1.5rem;
+
+@import "~bootstrap/scss/bootstrap";
@import "main.scss";
@import "portrait.scss";
@import "landscape.scss";
-@import "~@fortawesome/fontawesome-free/css/all.min.css"; \ No newline at end of file
+@import "~@fortawesome/fontawesome-free/css/all.min.css";
+
diff --git a/src/styles/landscape.scss b/src/styles/landscape.scss
index 4742273..b7e1bf7 100644
--- a/src/styles/landscape.scss
+++ b/src/styles/landscape.scss
@@ -3,18 +3,4 @@
html {
background-image: url('../images/horizontal_background.png');
}
-
- body {
-
- .center {
- width: 80%;
- float: left;
- }
-
- .bottom {
- flex-direction: column;
- width: 20%;
- }
-
- }
} \ No newline at end of file
diff --git a/src/styles/main.scss b/src/styles/main.scss
index 84d877c..626d127 100644
--- a/src/styles/main.scss
+++ b/src/styles/main.scss
@@ -17,167 +17,10 @@ html {
}
body {
- font-size: 2rem;
- font-family: Arial;
- color: map-get($colors, font);
- margin: 0 5%;
- height: 100%;
-
- a {
- color: map-get($colors, font);
- text-decoration: none;
- }
-
- .button {
- &[value="true"] {
- color: map-get($colors, primary);
- .disabled {
- display: none;
- }
- .enabled {
- display: block;
- }
- }
- &[value="false"] {
- color: map-get($colors, grey);
- .disabled {
- display: block;
- }
- .enabled {
- display: none;
- }
- }
- }
-
- .page {
- flex-direction: column;
- flex-wrap: nowrap;
- justify-content: center;
- height: 100%;
- overflow: hidden;
- position: relative;
-
- &.hide {
- display: none;
- }
-
- .header {
- text-align: left;
- margin: 50px 0;
-
- .backButton {
- padding-right: 20px;
- font-size: 1em;
- }
- }
-
- .container {
- overflow-y: scroll;
- height: 1040px;
-
- .entry {
- $entryHeight: 120px;
- height: $entryHeight;
- line-height: $entryHeight;
- border-bottom: 9 solid map-get($colors, grey);
-
- &:nth-last-child(1) {
- margin-bottom: 90px;
- }
-
- &.secondary {
- $entryHeight: 90px;
- }
-
- &:last-child {
- border-bottom: none;
- }
-
- .icon {
- width: 10%;
- height: $entryHeight;
- position: relative;
- float: left;
- text-align: center;
- }
-
- .label {
- position: relative;
- float: left;
- text-align: left;
- width: 75%;
- height: $entryHeight;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-
- .title {
- height: 2*$entryHeight/3;
- line-height: 2*$entryHeight/3;
- }
- .subtitle {
- height: $entryHeight/3;
- line-height: $entryHeight/3;
- font-size: 0.75em;
- }
- }
-
- .control {
- width: 15%;
- position: relative;
- float: left;
- text-align: right;
- height: $entryHeight;
-
- & > * {
- height: $entryHeight;
- line-height: $entryHeight;
- }
-
- &.enabled {
- .on {
- display: block;
- color: map-get($colors, primary);
- }
-
- .off {
- display: none;
- }
- }
-
- .on {
- display: none;
- }
-
- .off {
- display: block;
- }
- }
- }
- }
-
- .footer {
- position: absolute;
- bottom: 0;
- text-align: center;
- height: 80px;
- line-height: 80px;
- width: 100%;
- display: flex;
- flex-direction: row;
- flex-wrap: nowrap;
- justify-content: space-evenly;
- align-content: stretch;
-
- .button {
- flex-grow: 1;
- background: map-get($colors, secondary);
-
- &.active {
- background: map-get($colors, primary);
- }
- }
- }
+
+ .list-group.scrollable {
+ height: 720px;
+ overflow: scroll;
}
.log {
diff --git a/src/styles/portrait.scss b/src/styles/portrait.scss
index 4016600..f8db5e4 100644
--- a/src/styles/portrait.scss
+++ b/src/styles/portrait.scss
@@ -7,10 +7,4 @@
background-color: transparent;
height: 992px;
}
-
- body {
- .center {
- width: 100%;
- }
- }
} \ No newline at end of file
diff --git a/src/templates/bluetooth.template.html b/src/templates/bluetooth.template.html
new file mode 100644
index 0000000..dc732d7
--- /dev/null
+++ b/src/templates/bluetooth.template.html
@@ -0,0 +1,52 @@
+<div class="container">
+ <h2 class="my-5">
+ <div class="row">
+ <div class="col-1" onclick="bluetooth.hide()">
+ <i class="fas fa-chevron-left"></i>
+ </div>
+ <div class="col-10">
+ Bluetooth
+ </div>
+ <div class="col-1" onclick="bluetooth.show()">
+ <i class="fas fa-sync"></i>
+ </div>
+ </div>
+ </h2>
+ <div class="list-group scrollable">
+ {{ #devices }}
+ <div class="row border-bottom py-3 list-group-action">
+ <div class="col-1">
+ <i class="fab fa-bluetooth"></i>
+ </div>
+ <div class="col-9" onclick="bluetooth.manage('{{device}}', {{properties.paired}}, {{ properties.connected }})">
+ <div>
+ {{ properties.name }}
+ </div>
+ <div class="badge badge-secondary">
+ {{ properties.address}}
+ </div>
+ </div>
+ <div class="col-2 text-right" onclick="bluetooth.remove('{{device}}')">
+ <i class="fa fa-trash"></i>
+ </div>
+ </div>
+ {{ /devices }}
+ </div>
+ <div class="btn-group fixed-bottom" role="group" aria-label="Basic example">
+ <button type="button"
+ onclick="bluetooth.available()"
+ class="btn {{ ^filter.available }} btn-secondary {{ /filter.available }}{{ #filter.available }} btn-primary {{ /filter.available }}">
+ Available
+ </button>
+ <button type="button"
+ onclick="bluetooth.paired()"
+ class="btn {{ ^filter.paired }} btn-secondary {{ /filter.paired }}{{ #filter.paired }} btn-primary {{ /filter.paired }}">
+ Paired
+ </button>
+ <button type="button"
+ onclick="bluetooth.connected()"
+ class="btn {{ ^filter.connected }} btn-secondary {{ /filter.connected }}{{ #filter.connected }} btn-primary {{ /filter.connected }}">
+ Connected
+ </button>
+ </div>
+</div> \ No newline at end of file
diff --git a/src/templates/main.template.html b/src/templates/main.template.html
new file mode 100644
index 0000000..6965b5a
--- /dev/null
+++ b/src/templates/main.template.html
@@ -0,0 +1,73 @@
+<div class="container">
+ <h2 class="my-5">
+ Settings
+ </h2>
+ <div class="row border-bottom py-3">
+ <div class="col-1">
+ <i class="fa fa-clock"></i>
+ </div>
+ <div class="col-9">
+ Date & Time
+ </div>
+ <div class="col-2 text-right">
+
+ </div>
+ </div>
+ <div class="row border-bottom py-3">
+ <div class="col-1">
+ <i class="fab fa-bluetooth-b"></i>
+ </div>
+ <div class="col-9" onclick="window.bluetooth.show()">
+ Bluetooth
+ </div>
+ <div class="col-2 text-right">
+ {{ #bluetooth }}
+ <span class="fa fa-toggle-on on text-primary"></span>
+ {{ /bluetooth }}
+ {{ ^bluetooth }}
+ <span class="fa fa-toggle-off off"></span>
+ {{ /bluetooth }}
+ </div>
+ </div>
+ <div class="row border-bottom py-3">
+ <div class="col-1">
+ <i class="fas fa-wifi"></i>
+ </div>
+ <div class="col-9">
+ Wifi
+ </div>
+ <div class="col-2 text-right">
+ {{ #wifi }}
+ <span class="fa fa-toggle-on on text-primary"></span>
+ {{ /wifi }}
+ {{ ^wifi }}
+ <span class="fa fa-toggle-off off"></span>
+ {{ /wifi }}
+ </div>
+ </div>
+ <div class="row border-bottom py-3">
+ <div class="col-1">
+ <i class="fas fa-network-wired"></i>
+ </div>
+ <div class="col-9">
+ Wired
+ </div>
+ <div class="col-2 text-right">
+
+ </div>
+ </div>
+ <div class="row py-3">
+ <div class="col-1">
+ <i class="fas fa-tachometer-alt"></i>
+ </div>
+ <div class="col-9">
+ Version info
+ </div>
+ <div class="col-2 text-right">
+
+ </div>
+ </div>
+</div>
+<div class="log" id="log">
+
+</div> \ No newline at end of file
diff --git a/webpack.config.js b/webpack.config.js
index d64373c..b6177cc 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -42,6 +42,11 @@ module.exports = {
from: 'src/images/*',
to: 'images/',
flatten: true
+ },
+ {
+ from: 'src/templates/*',
+ to: 'templates/',
+ flatten: true
}
]),
new HtmlWebpackPlugin({