aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHumberto Alfonso Díaz <humberto.alfonso@asvito.es>2019-10-23 09:44:29 +0200
committerLorenzo Tilve <ltilve@igalia.com>2020-02-04 19:20:13 +0100
commit33702aea7ce42c8240e4bed7b424cc8ac4a33826 (patch)
tree6bba05249b6830fa6cdaea1bbd88971e8e027634
parent00b8929291665238cbcd88676fe65f67900be1c3 (diff)
FUNCT Implement bluetooth screen
-rw-r--r--package.json3
-rw-r--r--src/index.html111
-rw-r--r--src/index.js12
-rw-r--r--src/js/AFB.js215
-rw-r--r--src/js/app.js8
-rw-r--r--src/js/bluetooth.js50
-rwxr-xr-xsrc/styles/fonts/icomoon.eotbin1976 -> 2300 bytes
-rwxr-xr-xsrc/styles/fonts/icomoon.svg5
-rwxr-xr-xsrc/styles/fonts/icomoon.ttfbin1812 -> 2136 bytes
-rwxr-xr-xsrc/styles/fonts/icomoon.woffbin1888 -> 2212 bytes
-rw-r--r--src/styles/main.scss90
-rwxr-xr-xsrc/styles/style.css25
12 files changed, 220 insertions, 299 deletions
diff --git a/package.json b/package.json
index ecde60e..1109399 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
"zip-webpack-plugin": "^3.0.0"
},
"dependencies": {
- "mustache": "^3.1.0"
+ "mustache": "^3.1.0",
+ "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 65d316c..6f16a23 100644
--- a/src/index.html
+++ b/src/index.html
@@ -25,52 +25,55 @@
<h1 class="header">
Settings
</h1>
- <a href="#" class="entry" onclick="window.show('datetime');">
- <div class="icon">
- <span class="icon-time"></span>
- </div>
- <div class="label">
- Date & Time
- </div>
- </a>
- <a href="#" class="entry" onclick="window.show('bluetooth');">
- <div class="icon">
- <span class="icon-bluetooth"></span>
- </div>
- <div class="label">
- Bluetooth
- </div>
- <div class="control">
- <span class="icon-toggle_on"></span>
- </div>
- </a>
- <a href="#" class="entry" onclick="window.show('wifi');">
- <div class="icon">
- <span class="icon-wifi"></span>
- </div>
- <div class="label">
- Wifi
- </div>
- <div class="control">
- <span class="icon-toggle_off"></span>
- </div>
- </a>
- <a href="#" class="entry" onclick="window.show('wired');">
- <div class="icon">
- <span class="icon-ethernet"></span>
- </div>
- <div class="label">
- Wired
- </div>
- </a>
- <a href="#" class="entry" onclick="window.show('version');">
- <div class="icon">
- <span class="icon-speed"></span>
- </div>
- <div class="label">
- Version info
- </div>
- </a>
+ <div class="container">
+ <a href="#" class="entry" onclick="window.show('datetime');">
+ <div class="icon">
+ <span class="icon-time"></span>
+ </div>
+ <div class="label">
+ Date & Time
+ </div>
+ </a>
+ <a href="#" class="entry">
+ <div class="icon">
+ <span class="icon-bluetooth"></span>
+ </div>
+ <div class="label" onclick="window.show('bluetooth');">
+ Bluetooth
+ </div>
+ <div id="BluetoothControl" class="control enabled" onclick="window.toggle_bluetooth();">
+ <span class="icon-toggle_on"></span>
+ <span class="icon-toggle_off"></span>
+ </div>
+ </a>
+ <a href="#" class="entry" onclick="window.show('wifi');">
+ <div class="icon">
+ <span class="icon-wifi"></span>
+ </div>
+ <div class="label">
+ Wifi
+ </div>
+ <div class="control">
+ <span class="icon-toggle_off"></span>
+ </div>
+ </a>
+ <a href="#" class="entry" onclick="window.show('wired');">
+ <div class="icon">
+ <span class="icon-ethernet"></span>
+ </div>
+ <div class="label">
+ Wired
+ </div>
+ </a>
+ <a href="#" class="entry" onclick="window.show('version');">
+ <div class="icon">
+ <span class="icon-speed"></span>
+ </div>
+ <div class="label">
+ Version info
+ </div>
+ </a>
+ </div>
</div>
<div class="secondary page hide" id="datetime">
@@ -94,8 +97,22 @@
<div class="secondary page hide" id="bluetooth">
<h1 class="header">
- Bluetotth
+ Bluetooth
</h1>
+ <div id="BluetoothContainer" class="container"></div>
+ <script id="bluetooth-device-template" type="x-tmpl-mustache">
+ <a href="#" class="entry">
+ <div class="icon">
+ <span class="icon-{{ properties.icon }}"></span>
+ </div>
+ <div class="label">
+ {{ properties.name }}
+ </div>
+ <div class="control">
+ <span class="icon-clear"></span>
+ </div>
+ </a>
+ </script>
<a href="#" class="confirm button" onclick="window.hide('bluetooth')">
Confirm
</a>
diff --git a/src/index.js b/src/index.js
index ded8fe7..efdafaa 100644
--- a/src/index.js
+++ b/src/index.js
@@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
/* JS */
-import './js/AFB.js';
+import { init } from './js/app';
+import { toggle as toggle_bluetooth } from './js/bluetooth';
/* CSS */
import './styles/app.scss';
@@ -28,4 +28,10 @@ window.show = function(page){
window.hide = function(page) {
document.getElementById('main').classList.remove('hide');
document.getElementById(page).classList.add('hide');
-} \ No newline at end of file
+}
+
+window.toggle_bluetooth = function() {
+ toggle_bluetooth();
+}
+
+init(); \ No newline at end of file
diff --git a/src/js/AFB.js b/src/js/AFB.js
deleted file mode 100644
index d6e6bfa..0000000
--- a/src/js/AFB.js
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2017, 2018 "IoT.bzh"
- * Author: José Bollo <jose.bollo@iot.bzh>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-AFB = function(base, initialtoken){
-
-if (typeof base != "object")
- base = { base: base, token: initialtoken };
-
-var initial = {
- base: base.base || "api",
- token: base.token || initialtoken || "HELLO",
- host: base.host || window.location.host,
- url: base.url || undefined
-};
-
-var urlws = initial.url || "ws://"+initial.host+"/"+initial.base;
-
-/*********************************************/
-/**** ****/
-/**** AFB_context ****/
-/**** ****/
-/*********************************************/
-var AFB_context;
-{
- var UUID = undefined;
- var TOKEN = initial.token;
-
- var context = function(token, uuid) {
- this.token = token;
- this.uuid = uuid;
- }
-
- context.prototype = {
- get token() {return TOKEN;},
- set token(tok) {if(tok) TOKEN=tok;},
- get uuid() {return UUID;},
- set uuid(id) {if(id) UUID=id;}
- };
-
- AFB_context = new context();
-}
-/*********************************************/
-/**** ****/
-/**** AFB_websocket ****/
-/**** ****/
-/*********************************************/
-var AFB_websocket;
-{
- var CALL = 2;
- var RETOK = 3;
- var RETERR = 4;
- var EVENT = 5;
-
- var PROTO1 = "x-afb-ws-json1";
-
- AFB_websocket = function(on_open, on_abort) {
- var u = urlws, p = '?';
- if (AFB_context.token) {
- u = u + '?x-afb-token=' + AFB_context.token;
- p = '&';
- }
- if (AFB_context.uuid)
- u = u + p + 'x-afb-uuid=' + AFB_context.uuid;
- this.ws = new WebSocket(u, [ PROTO1 ]);
- this.url = u;
- this.pendings = {};
- this.awaitens = {};
- this.counter = 0;
- this.ws.onopen = onopen.bind(this);
- this.ws.onerror = onerror.bind(this);
- this.ws.onclose = onclose.bind(this);
- this.ws.onmessage = onmessage.bind(this);
- this.onopen = on_open;
- this.onabort = on_abort;
- }
-
- function onerror(event) {
- var f = this.onabort;
- if (f) {
- delete this.onopen;
- delete this.onabort;
- f && f(this);
- }
- this.onerror && this.onerror(this);
- }
-
- function onopen(event) {
- var f = this.onopen;
- delete this.onopen;
- delete this.onabort;
- f && f(this);
- }
-
- function onclose(event) {
- var err = {
- jtype: 'afb-reply',
- request: {
- status: 'disconnected',
- info: 'server hung up'
- }
- };
- for (var id in this.pendings) {
- try { this.pendings[id][1](err); } catch (x) {/*NOTHING*/}
- }
- this.pendings = {};
- this.onclose && this.onclose();
- }
-
- function fire(awaitens, name, data) {
- var a = awaitens[name];
- if (a)
- a.forEach(function(handler){handler(data);});
- var i = name.indexOf("/");
- if (i >= 0) {
- a = awaitens[name.substring(0,i)];
- if (a)
- a.forEach(function(handler){handler(data);});
- }
- a = awaitens["*"];
- if (a)
- a.forEach(function(handler){handler(data);});
- }
-
- function reply(pendings, id, ans, offset) {
- if (id in pendings) {
- var p = pendings[id];
- delete pendings[id];
- try { p[offset](ans); } catch (x) {/*TODO?*/}
- }
- }
-
- function onmessage(event) {
- var obj = JSON.parse(event.data);
- var code = obj[0];
- var id = obj[1];
- var ans = obj[2];
- AFB_context.token = obj[3];
- switch (code) {
- case RETOK:
- reply(this.pendings, id, ans, 0);
- break;
- case RETERR:
- reply(this.pendings, id, ans, 1);
- break;
- case EVENT:
- default:
- fire(this.awaitens, id, ans);
- break;
- }
- }
-
- function close() {
- this.ws.close();
- this.ws.onopen =
- this.ws.onerror =
- this.ws.onclose =
- this.ws.onmessage =
- this.onopen =
- this.onabort = function(){};
- }
-
- function call(method, request, callid) {
- return new Promise((function(resolve, reject){
- var id, arr;
- if (callid) {
- id = String(callid);
- if (id in this.pendings)
- throw new Error("pending callid("+id+") exists");
- } else {
- do {
- id = String(this.counter = 4095 & (this.counter + 1));
- } while (id in this.pendings);
- }
- this.pendings[id] = [ resolve, reject ];
- arr = [CALL, id, method, request ];
- if (AFB_context.token) arr.push(AFB_context.token);
- this.ws.send(JSON.stringify(arr));
- }).bind(this));
- }
-
- function onevent(name, handler) {
- var id = name;
- var list = this.awaitens[id] || (this.awaitens[id] = []);
- list.push(handler);
- }
-
- AFB_websocket.prototype = {
- close: close,
- call: call,
- onevent: onevent
- };
-}
-/*********************************************/
-/**** ****/
-/**** ****/
-/**** ****/
-/*********************************************/
-return {
- context: AFB_context,
- ws: AFB_websocket
-};
-};
diff --git a/src/js/app.js b/src/js/app.js
new file mode 100644
index 0000000..8e80039
--- /dev/null
+++ b/src/js/app.js
@@ -0,0 +1,8 @@
+import { init as init_bluetooth } from './bluetooth';
+
+import { api } from 'agl-js-api';
+
+export function init() {
+ api.init();
+ init_bluetooth();
+} \ No newline at end of file
diff --git a/src/js/bluetooth.js b/src/js/bluetooth.js
new file mode 100644
index 0000000..679ef0b
--- /dev/null
+++ b/src/js/bluetooth.js
@@ -0,0 +1,50 @@
+import { bluetooth } from 'agl-js-api';
+import Mustache from 'mustache';
+
+var isPowered = false;
+var template;
+
+function update_state(state) {
+ var control = document.getElementById('BluetoothControl');
+ if( state.powered ) {
+ control.classList.add('enabled');
+ } else {
+ control.classList.remove('enabled');
+ }
+}
+
+function update_devices(devices) {
+ console.log('update_devices', devices);
+ var deviceList = document.getElementById('BluetoothContainer');
+ deviceList.innerHTML = '';
+
+ devices.forEach(function(device) {
+ deviceList.innerHTML += Mustache.render(template, device);
+ });
+}
+
+export function toggle() {
+ bluetooth.adapter_state().then(function(result) {
+ bluetooth.adapter_state({
+ powered: !result.powered
+ }).then(update_state);
+ });
+}
+
+export function init() {
+ template = document.getElementById('bluetooth-device-template').innerHTML;
+ Mustache.parse(template);
+ bluetooth.adapter_state().then(update_state);
+
+ bluetooth.managed_objects().then(function(result){
+ update_devices(result.devices);
+ });
+
+ 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');
+ });
+} \ No newline at end of file
diff --git a/src/styles/fonts/icomoon.eot b/src/styles/fonts/icomoon.eot
index 060e952..fb55d1c 100755
--- a/src/styles/fonts/icomoon.eot
+++ b/src/styles/fonts/icomoon.eot
Binary files differ
diff --git a/src/styles/fonts/icomoon.svg b/src/styles/fonts/icomoon.svg
index ee686b7..6fedeea 100755
--- a/src/styles/fonts/icomoon.svg
+++ b/src/styles/fonts/icomoon.svg
@@ -14,4 +14,9 @@
<glyph unicode="&#xe904;" glyph-name="speed" d="M512 256.667q-34 0-60 25t-26 59q0 36 26 62l362 240-242-362q-24-24-60-24zM870 572.667q28-44 48-112t20-120q0-118-56-212-26-44-74-44h-592q-48 0-74 44-56 94-56 212 0 176 125 301t303 125q52 0 119-20t111-48l-80-52q-72 36-152 36-140 0-241-100t-101-242q0-92 46-170h592q46 78 46 170 0 82-36 154z" />
<glyph unicode="&#xe905;" glyph-name="toggle_off" d="M298 298.667q52 0 90 38t38 90-38 90-90 38-90-38-38-90 38-90 90-38zM726 640.667q88 0 150-63t62-151-62-151-150-63h-428q-88 0-150 63t-62 151 62 151 150 63h428z" />
<glyph unicode="&#xe906;" glyph-name="toggle_on" d="M726 298.667q52 0 90 38t38 90-38 90-90 38-90-38-38-90 38-90 90-38zM726 640.667q88 0 150-63t62-151-62-151-150-63h-428q-88 0-150 63t-62 151 62 151 150 63h428z" />
+<glyph unicode="&#xe907;" glyph-name="keyboard_arrow_down" d="M316 572.667l196-196 196 196 60-60-256-256-256 256z" />
+<glyph unicode="&#xe908;" glyph-name="keyboard_arrow_up" d="M316 280.667l-60 60 256 256 256-256-60-60-196 196z" />
+<glyph unicode="&#xe909;" glyph-name="clear" d="M810 664.667l-238-238 238-238-60-60-238 238-238-238-60 60 238 238-238 238 60 60 238-238 238 238z" />
+<glyph unicode="&#xe90a;" glyph-name="computer" d="M854 298.667v426h-684v-426h684zM598 170.667v42h-172v-42h172zM938 170.667h86v-86h-1024v86h86v640h852v-640z" />
+<glyph unicode="&#xe90b;" glyph-name="phone" d="M736 170.667v598h-448v-598h448zM598 42.667v42h-172v-42h172zM682 896.667q52 0 90-38t38-90v-684q0-52-38-90t-90-38h-340q-52 0-90 38t-38 90v684q0 52 38 90t90 38h340z" />
</font></defs></svg> \ No newline at end of file
diff --git a/src/styles/fonts/icomoon.ttf b/src/styles/fonts/icomoon.ttf
index 1c80635..ec51acb 100755
--- a/src/styles/fonts/icomoon.ttf
+++ b/src/styles/fonts/icomoon.ttf
Binary files differ
diff --git a/src/styles/fonts/icomoon.woff b/src/styles/fonts/icomoon.woff
index 035641c..ca1195e 100755
--- a/src/styles/fonts/icomoon.woff
+++ b/src/styles/fonts/icomoon.woff
Binary files differ
diff --git a/src/styles/main.scss b/src/styles/main.scss
index 518bdc2..6b917d1 100644
--- a/src/styles/main.scss
+++ b/src/styles/main.scss
@@ -53,9 +53,10 @@ body {
.page {
display: flex;
flex-direction: column;
- flex-wrap: wrap;
+ flex-wrap: nowrap;
justify-content: center;
height: 100%;
+ overflow: hidden;
&.hide {
display: none;
@@ -66,42 +67,75 @@ body {
margin: 0;
}
- .entry {
- height: 120px;
- line-height: 120px;
- border-bottom: 1px solid map-get($colors, grey);
+ .container {
+ display: flex;
+ flex-direction: column;
+ flex-wrap: nowrap;
+ justify-content: center;
+ flex-grow: 2;
- &:last-child {
- border-bottom: none2;
- }
+ .entry {
+ height: 120px;
+ line-height: 120px;
+ border-bottom: 1px solid map-get($colors, grey);
- .icon {
- width: 10%;
- position: relative;
- float: left;
- text-align: center;
- }
+ &:last-child {
+ border-bottom: none;
+ }
- .label {
- position: relative;
- float: left;
- text-align: left;
- width: 80%;
- }
+ .icon {
+ width: 10%;
+ position: relative;
+ float: left;
+ text-align: center;
+ }
- .control {
- width: 10%;
- position: relative;
- float: left;
- text-align: right;
- font-size: 5rem;
+ .label {
+ position: relative;
+ float: left;
+ text-align: left;
+ width: 75%;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
- .icon-toggle_on {
- color: map-get($colors, primary);
+ .control {
+ width: 15%;
+ position: relative;
+ float: left;
+ text-align: right;
+ font-size: 5rem;
+
+ & > * {
+ height: 120px;
+ line-height: 120px;
+ }
+
+ &.enabled {
+ .icon-toggle_on {
+ display: block;
+ color: map-get($colors, primary);
+ }
+
+ .icon-toggle_off {
+ display: none;
+ }
+ }
+
+ .icon-toggle_on {
+ display: none;
+ }
+
+ .icon-toggle_off {
+ display: block;
+ }
}
}
}
+
+
.confirm {
position: absolute;
bottom: 5%;
diff --git a/src/styles/style.css b/src/styles/style.css
index 0bd7eb9..e656a4e 100755
--- a/src/styles/style.css
+++ b/src/styles/style.css
@@ -1,10 +1,10 @@
@font-face {
font-family: 'icomoon';
- src: url('fonts/icomoon.eot?h6r2e7');
- src: url('fonts/icomoon.eot?h6r2e7#iefix') format('embedded-opentype'),
- url('fonts/icomoon.ttf?h6r2e7') format('truetype'),
- url('fonts/icomoon.woff?h6r2e7') format('woff'),
- url('fonts/icomoon.svg?h6r2e7#icomoon') format('svg');
+ src: url('fonts/icomoon.eot?6brftk');
+ src: url('fonts/icomoon.eot?6brftk#iefix') format('embedded-opentype'),
+ url('fonts/icomoon.ttf?6brftk') format('truetype'),
+ url('fonts/icomoon.woff?6brftk') format('woff'),
+ url('fonts/icomoon.svg?6brftk#icomoon') format('svg');
font-weight: normal;
font-style: normal;
font-display: block;
@@ -25,12 +25,27 @@
-moz-osx-font-smoothing: grayscale;
}
+.icon-clear:before {
+ content: "\e909";
+}
.icon-time:before {
content: "\e900";
}
.icon-bluetooth:before {
content: "\e901";
}
+.icon-keyboard_arrow_down:before {
+ content: "\e907";
+}
+.icon-keyboard_arrow_up:before {
+ content: "\e908";
+}
+.icon-computer:before {
+ content: "\e90a";
+}
+.icon-phone:before {
+ content: "\e90b";
+}
.icon-wifi:before {
content: "\e902";
}