From abbbcc17e972d22c3e606a1fc0fef4bd2a083bb3 Mon Sep 17 00:00:00 2001 From: peteruithoven Date: Mon, 24 Feb 2014 11:26:30 +0100 Subject: [PATCH] Guiding users to connect box to WiFi network --- css/main.css | 131 ++++++++++++++++--- index.html | 27 +++- js/Box.js | 78 +++++++++++ js/NetworkPanel.js | 304 +++++++++++++++++++++++++++++++++++++++++++ js/api/ConnectAPI.js | 36 +++++ js/api/NetworkAPI.js | 150 +++++++++++++++++++++ js/main.js | 179 ++++++++++++++----------- 7 files changed, 811 insertions(+), 94 deletions(-) create mode 100644 js/Box.js create mode 100644 js/NetworkPanel.js create mode 100644 js/api/ConnectAPI.js create mode 100644 js/api/NetworkAPI.js diff --git a/css/main.css b/css/main.css index 7b0fcb9..5fb99f4 100644 --- a/css/main.css +++ b/css/main.css @@ -30,17 +30,20 @@ a { #list { padding: 0; } -#list li { + +.box{ list-style-type: none; float: left; -} -#list a { + margin: 0 15px 15px 0; - padding: 25px 0 0 0; + /*padding: 25px;*/ + padding: 0 0 25px 0; display: block; + position: relative; - width: 200px; - height: 175px; + min-width: 200px; /*175px;*/ + min-height: 175px; /*175px;*/ + /*height: 275px;*/ border: 2px solid #333; border-radius: 25px; @@ -49,28 +52,118 @@ a { -webkit-box-shadow: 0px 2px 7px 0px rgba(16, 16, 16, 0.60); box-shadow: 0px 2px 7px 0px rgba(16, 16, 16, 0.60); - text-align: center; - vertical-align: middle; - cursor: pointer; - transition:background-color 0.1s, color 0.1s; } -#list a:hover { +.box:hover { background-color: #5491D2; +} +.box:hover a{ color: #fff; } +.box.complex { + width: 375px; /*320px;*/ + /*border: 2px solid #00f;*/ +} +box.connecting { + border: 2px solid #ff0; +} +.box a{ + display:block; + padding: 25px 25px 12px 25px; + text-align: center; + + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; +} +.box.complex a { + position: relative; + top: auto; + right: auto; + bottom: auto; + left: auto; +} #hint { display:none; position: absolute; bottom: 1em; + line-height: 1.5; } -/*.vertImage {*/ - /*margin: 0;*/ - /*padding: 0;*/ - /*border: 2px solid #f0f;*/ - /*max-width: 100%;*/ - /*height: auto;*/ - /*width: auto; *//* for ie9 */ -/*}*/ +#networkForm { + display: none; +} +.box .networkForm { + display: none; +} +.box.complex .networkForm { + display: block; +} + + +/* NETWORK PANEL */ +.networkForm { + background-color: #fff; + /*border-radius: 0 0 25px 25px;*/ + padding: 12px 25px 12px 25px; +} + +form p { + margin: 0 0 10px 0; +} +form label { + min-width: 110px; + display: block; + float: left; + margin: 1px 0 10px 0; + clear: left; +} +form label.inline { + display: inline; + float: none; +} +form div { + float: left; +} +form input[type="text"], form input[type="number"], form input[type="password"] { + border: 1px solid rgb(144, 192, 255); + margin-right: 5px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + + width: 130px; +} +form .button { + display: inline-block; +} + +.networkForm #network { + margin-right: 5px; + width: 130px; +} + +.networkForm #ssid, +.networkForm #listNetworks, +.networkForm #passwordSettings { + display: none; +} + +.networkForm.customNetwork #passwordSettings { + display: block; +} +.networkForm.customNetwork #ssid, +.networkForm.customNetwork #listNetworks{ + display: inline-block; +} +.networkForm.customNetwork #network, +.networkForm.customNetwork #refreshNetworks { + display: none; +} +.networkForm #btnConnect { + display: block; + clear:left; +} \ No newline at end of file diff --git a/index.html b/index.html index fae52d8..cd6d2a4 100644 --- a/index.html +++ b/index.html @@ -18,7 +18,11 @@ - + + + + + @@ -38,7 +42,7 @@ Can’t find your box?
- Maybe the box isn’t connected to your network yet, try to connect to a Doodle3D-... WiFi network.
+ Maybe your box isn’t connected to your network yet, try to connect to a Doodle3D-... WiFi network.
Otherwise, make sure you’re on the same WiFi network.
You can always connect your box to your computer using an ethernet cable.
@@ -48,6 +52,25 @@ + +
+

Connect box to your WiFi network:

+ +
+
+
+ +
+
+
+ + +
+
+
+ +
+
\ No newline at end of file diff --git a/js/Box.js b/js/Box.js new file mode 100644 index 0000000..9fba3c6 --- /dev/null +++ b/js/Box.js @@ -0,0 +1,78 @@ +/* + * This file is part of the Doodle3D project (http://doodle3d.com). + * + * Copyright (c) 2013, Doodle3D + * This software is licensed under the terms of the GNU GPL v2 or later. + * See file LICENSE.txt or visit http://www.gnu.org/licenses/gpl.html for full license details. + */ +function Box() { + + this.localip; + this.wifiboxid; + this.connecting = false; + this.destroyedHandler; + + var _element; + var _networkPanel; + var _delayedDestroy; + var _self = this; + + this.init = function(boxData,parentElement) { + + _self.localip = boxData.localip; + _self.wifiboxid = boxData.wifiboxid; + var url = "http://"+_self.localip; + + // create box dom element + var link = (boxData.link)? boxData.link : url; + _element = $("
  • "); + _element.append(""+_self.wifiboxid+""); + _element.hide().appendTo(parentElement).fadeIn(500); + + // create network panel dom element + var networkPanelElement = $("#networkForm").clone(); + networkPanelElement.addClass(networkPanelElement.attr("id")); + networkPanelElement.removeAttr("id"); + _element.append(networkPanelElement); + + // create network panel + _networkPanel = new NetworkPanel(); + _networkPanel.id = _self.localip; + _networkPanel.init(url,networkPanelElement, networkStatusChangeHandler); + + } + function networkStatusChangeHandler(networkStatus) { + console.log("Box:networkStatusChangeHandler: ",networkStatus); + _self.connecting = (networkStatus == NetworkAPI.STATUS.CONNECTING); + + // because openwrt can be slow to update it's ssid, a box might + // report it failed connecting but is then slightly later connects + // so we correct CONNECTING_FAILED to CONNECTED unless the box is connected by wire + if(_self.localip != "192.168.5.1" && networkStatus == NetworkAPI.STATUS.CONNECTING_FAILED) { + networkStatus = NetworkAPI.STATUS.CONNECTED; + } + + _element.toggleClass("complex",(networkStatus !== NetworkAPI.STATUS.CONNECTED)); + + if(_self.connecting) { + clearTimeout(_delayedDestroy); + _delayedDestroy = setTimeout(function() { + console.log("delayed remove"); + //removeBox(box,true); + _self.destroy() + }, 10000); + } + } + this.destroy = function() { + console.log("Box:destroy"); + clearTimeout(_delayedDestroy); + + _networkPanel.destroy(); + + _element.fadeOut(500,function() { + _element.remove(); + }); + + if(_self.destroyedHandler) _self.destroyedHandler(_self); + } +} \ No newline at end of file diff --git a/js/NetworkPanel.js b/js/NetworkPanel.js new file mode 100644 index 0000000..a47bdad --- /dev/null +++ b/js/NetworkPanel.js @@ -0,0 +1,304 @@ +/* + * This file is part of the Doodle3D project (http://doodle3d.com). + * + * Copyright (c) 2013, Doodle3D + * This software is licensed under the terms of the GNU GPL v2 or later. + * See file LICENSE.txt or visit http://www.gnu.org/licenses/gpl.html for full license details. + */ + +function NetworkPanel() { + + this.id; + + var NETWORK_SELECTOR_DEFAULT = "please select"; // used as first item in networks list + //var NETWORK_SELECTOR_CUSTOM = "join other network..."; + + // network mode + NetworkPanel.NETWORK_MODE = { + NEITHER: "neither", + CLIENT: "clientMode", + ACCESS_POINT: "accessPointMode" + }; + var _networkMode = NetworkPanel.NETWORK_MODE.NEITHER; + + var _api = new NetworkAPI(); + var _networks = {}; + var _currentNetwork; // the ssid of the network the box is on + var _selectedNetwork; // the ssid of the selected network in the client mode settings + + var _currentNetworkStatus; + var _customNetwork = false; + + var _retryDelay = 2000; + var _retryRetrieveStatusDelayTime = 1000; + var _retryRetrieveStatusDelay; + var _retrieveStatusDelayTime = 1000; + var _retrieveStatusDelay; + + var _statusChangeHandler; + + // ui elements + var _element; + var _networkSelector; + var _btnRefreshNetworks; + var _networkField; + var _btnListNetworks; + var _passwordSettings; + var _passwordField; + var _showPassword; + var _btnConnect; + var _statusTextField; + + var _self = this; + + this.init = function(wifiboxURL,panelElement,statusChangeHandler) { + + //console.log(_self.id,"NetworkPanel:init"); + + _api.init(wifiboxURL); + + _element = panelElement; + _networkSelector = _element.find("#network"); + _btnRefreshNetworks = _element.find("#refreshNetworks"); + _networkField = _element.find("#ssid"); + _btnListNetworks = _element.find("#listNetworks"); + _passwordSettings = _element.find("#passwordSettings"); + _passwordField = _element.find("#phrase"); + _showPassword = _element.find("#showPassword"); + _btnConnect = _element.find("#btnConnect"); + _statusTextField = _element.find("#statusText"); + + _btnRefreshNetworks.on('touchstart mousedown',onRefreshClick); + _btnListNetworks.on('touchstart mousedown',showNetworkSelector); + _btnConnect.on('touchstart mousedown',_self.connectToNetwork); + _networkSelector.change(networkSelectorChanged); + _showPassword.change(showPassWordToggle); + + _statusChangeHandler = statusChangeHandler; + + _self.retrieveStatus(function(networkStatus) { + if(networkStatus != NetworkAPI.STATUS.CONNECTED) { + _self.refreshNetworks(); + } + }); + } + /* + * Handlers + */ + function onRefreshClick() { + _btnRefreshNetworks.attr("disabled", true); + _self.refreshNetworks(function() { + _btnRefreshNetworks.removeAttr("disabled"); + }) + } + function networkSelectorChanged(e) { + var selectedOption = $(this).find("option:selected"); + _self.selectNetwork(selectedOption.val()); + }; + function showPassWordToggle() { + var type = (_showPassword.prop('checked'))? "text" : "password"; + //console.log(" type: ",type); + _passwordField.attr("type",type); + }; + + this.retrieveStatus = function(completeHandler) { + //console.log(_self.id,"NetworkPanel:retrieveStatus"); + _api.status(function(data) { + if(typeof data.status === 'string') { + data.status = parseInt(data.status); + } + //console.log(_self.id,"NetworkPanel:retrievedStatus status: ",data.status,data.statusMessage); + //console.log(" networkPanel ",_element[0]," parent: ",_element.parent()[0]); + // ToDo: update _currentNetwork when available + + setStatus(data.status,data); + + // Keep checking for updates? + switch(data.status) { + case NetworkAPI.STATUS.CONNECTING: + case NetworkAPI.STATUS.CREATING: + clearTimeout(_retryRetrieveStatusDelay); + _retryRetrieveStatusDelay = setTimeout(_self.retrieveStatus,_retryRetrieveStatusDelayTime); // retry after delay + break; + } + _currentNetworkStatus = data.status; + if(completeHandler) completeHandler(data.status); + }, function() { + //console.log("NetworkPanel:retrieveStatus failed"); + clearTimeout(_retryRetrieveStatusDelay); + _retryRetrieveStatusDelay = setTimeout(_self.retrieveStatus, _retryRetrieveStatusDelayTime); // retry after delay + }); + }; + function setStatus(status,data) { + if(status == _currentNetworkStatus) return; + _currentNetworkStatus = status; + + // update info + switch(status) { + case NetworkAPI.STATUS.CONNECTED: + //console.log(" data.ssid: ",data.ssid); + if(data.ssid == "") { + _currentNetwork = undefined; + //data.status = NetworkAPI.STATUS.NOT_CONNECTED; + setStatus(NetworkAPI.STATUS.NOT_CONNECTED); + } else { + _currentNetwork = data.ssid; + } + break; + case NetworkAPI.STATUS.CREATING: + case NetworkAPI.STATUS.CREATED: + _currentNetwork = undefined; + break; + } + // network selector + switch(status) { + case NetworkAPI.STATUS.NOT_CONNECTED: + case NetworkAPI.STATUS.CREATING: + case NetworkAPI.STATUS.CREATED: + _networkSelector.val(NETWORK_SELECTOR_DEFAULT); + break; + case NetworkAPI.STATUS.CONNECTED: + _self.selectNetwork(_currentNetwork); + break; + case NetworkAPI.STATUS.CONNECTING: + case NetworkAPI.STATUS.CONNECTING_FAILED: + // ToDo + break; + } + // connect button + switch(status) { + case NetworkAPI.STATUS.CONNECTING: + case NetworkAPI.STATUS.CREATING: + _btnConnect.attr("disabled", true); + break; + default: + _btnConnect.removeAttr("disabled"); + break; + } + // update status text + //updateStatusText(status,data.statusMessage); + var msg = ""; + switch(status) { + case NetworkAPI.STATUS.NOT_CONNECTED: + case NetworkAPI.STATUS.CREATING: + case NetworkAPI.STATUS.CREATED: + break; + case NetworkAPI.STATUS.CONNECTED: + msg = "Connected to: "+_currentNetwork+"."; + break; + case NetworkAPI.STATUS.CONNECTING: + msg = "Connecting... "; + var targetNetwork; + if(_selectedNetwork != undefined) { + targetNetwork = _selectedNetwork; + } else if(_currentNetwork != undefined) { + targetNetwork = _currentNetwork; + } + if(targetNetwork != undefined) { + msg += "
    Connect your device to "+targetNetwork+"."; + } + break; + case NetworkAPI.STATUS.CONNECTING_FAILED: + //msg = data.statusMessage; + msg = "Could not connect, please check password"; + break; + } + //console.log(" client display msg: ",msg); + _statusTextField.html(msg); + + if(_statusChangeHandler) _statusChangeHandler(status); + } + this.refreshNetworks = function(completeHandler) { + //console.log("NetworkPanel:refreshNetworks"); + _api.scan(function(data) { // completed + //console.log("NetworkPanel:scanned"); + + // order networks alphabetically + data.networks.sort(function (a, b) { + if (a.ssid > b.ssid) + return 1; + if (a.ssid < b.ssid) + return -1; + // a must be equal to b + return 0; + }); + + fillNetworkSelector(data.networks) + _networks = {}; + $.each(data.networks, function(index,network) { + _networks[network.ssid] = network; + }); + + if(completeHandler) completeHandler(); + }); + }; + function fillNetworkSelector(networks) { + var foundCurrentNetwork = false; + _networkSelector.empty(); + _networkSelector.append( + $("").val(NETWORK_SELECTOR_DEFAULT).html(NETWORK_SELECTOR_DEFAULT) + ); + $.each(networks, function(index,network) { + if(network.ssid == _currentNetwork) { + foundCurrentNetwork = true; + } + _networkSelector.append( + $("").val(network.ssid).html(network.ssid) + ); + }); + /*_networkSelector.append( + $("").val(NETWORK_SELECTOR_CUSTOM).html(NETWORK_SELECTOR_CUSTOM) + );*/ + if(foundCurrentNetwork) { + _networkSelector.val(_currentNetwork); + //_self.selectNetwork(_currentNetwork); + } + } + + this.selectNetwork = function(ssid) { + //console.log("NetworkPanel:selectNetwork: ",ssid); + if(ssid == "") return; + _selectedNetwork = ssid; + + var network = _networks[ssid]; + //console.log(" network: ",network); + /*if(ssid == NETWORK_SELECTOR_CUSTOM) { + showCustomNetworkInput(); + _passwordSettings.show(); + } else*/ if(network === undefined || network.encryption == "none" || ssid == NETWORK_SELECTOR_DEFAULT) { + _passwordSettings.hide(); + } else { + _passwordSettings.show(); + } + _passwordField.val(""); + }; + + function showNetworkSelector() { + _customNetwork = false; + _element.removeClass("customNetwork"); + _networkSelector.val(NETWORK_SELECTOR_DEFAULT); + } + /*function showCustomNetworkInput() { + _customNetwork = true; + _element.addClass("customNetwork"); + }*/ + + this.connectToNetwork = function() { + //console.log("NetworkPanel:connectToNetwork"); + if(_selectedNetwork == NETWORK_SELECTOR_DEFAULT) return; + + setStatus(NetworkAPI.STATUS.CONNECTING); // override status + + var ssid = (_customNetwork)? _networkField.val() : _selectedNetwork; + _api.associate(ssid,_passwordField.val(),true); + + // after switching wifi network or creating a access point we delay the status retrieval + // because the webserver needs time to switch it's status + clearTimeout(_retrieveStatusDelay); + _retrieveStatusDelay = setTimeout(_self.retrieveStatus, _retrieveStatusDelayTime); + }; + this.destroy = function() { + clearTimeout(_retryRetrieveStatusDelay); + clearTimeout(_retrieveStatusDelay); + } +} diff --git a/js/api/ConnectAPI.js b/js/api/ConnectAPI.js new file mode 100644 index 0000000..b54a4ec --- /dev/null +++ b/js/api/ConnectAPI.js @@ -0,0 +1,36 @@ +/* + * This file is part of the Doodle3D project (http://doodle3d.com). + * + * Copyright (c) 2013, Doodle3D + * This software is licensed under the terms of the GNU GPL v2 or later. + * See file LICENSE.txt or visit http://www.gnu.org/licenses/gpl.html for full license details. + */ +function ConnectAPI() { + + var _apiURL = "http://connect.doodle3d.com/api"; + var _timeoutTime = 3000; + + var _self = this; + + this.list = function(completeHandler,failedHandler) { + //console.log("ConnectAPI:list"); + $.ajax({ + url: _apiURL + "/list.php", + type: "GET", + dataType: 'json', + timeout: _timeoutTime, + success: function(response){ + //console.log("ConnectAPI:list response: ",response); + if(response.status == "error" || response.status == "fail") { + //console.log("ConnectAPI:list failed: ",response); + if(failedHandler) failedHandler(response); + } else { + completeHandler(response.data); + } + } + }).fail(function() { + //console.log("ConnectAPI:list failed"); + if(failedHandler) failedHandler(); + }); + }; +} \ No newline at end of file diff --git a/js/api/NetworkAPI.js b/js/api/NetworkAPI.js new file mode 100644 index 0000000..db0c6e1 --- /dev/null +++ b/js/api/NetworkAPI.js @@ -0,0 +1,150 @@ +/* + * This file is part of the Doodle3D project (http://doodle3d.com). + * + * Copyright (c) 2013, Doodle3D + * This software is licensed under the terms of the GNU GPL v2 or later. + * See file LICENSE.txt or visit http://www.gnu.org/licenses/gpl.html for full license details. + */ +function NetworkAPI() { + + NetworkAPI.STATUS = { + CONNECTING_FAILED: -1, + NOT_CONNECTED: 0, + CONNECTING: 1, + CONNECTED: 2, + CREATING: 3, + CREATED: 4 + }; + + var _apiPath = "/d3dapi"; + var _apiCGIPath = "/cgi-bin"+_apiPath; + + var _wifiboxURL; + var _wifiboxCGIBinURL; + var _timeoutTime = 3000; + + var _self = this; + + this.init = function(wifiboxURL) { + //console.log("NetworkAPI:init"); + //console.log(" wifiboxURL: ",wifiboxURL); + //console.log(" wifiboxCGIBinURL: ",wifiboxCGIBinURL); + _wifiboxURL = wifiboxURL+_apiPath; + _wifiboxCGIBinURL = wifiboxURL+_apiCGIPath; + } + this.scan = function(completeHandler,failedHandler) { + //console.log("NetworkAPI:scan"); + $.ajax({ + url: _wifiboxURL + "/network/scan", + type: "GET", + dataType: 'json', + timeout: _timeoutTime, + success: function(response){ + //console.log("NetworkAPI:scan response: ",response); + if(response.status == "error" || response.status == "fail") { + //console.log("NetworkAPI:scan failed: ",response); + if(failedHandler) failedHandler(response); + } else { + completeHandler(response.data); + } + } + }).fail(function() { + //console.log("NetworkAPI:scan failed"); + if(failedHandler) failedHandler(); + }); + }; + this.status = function(completeHandler,failedHandler) { + //console.log("NetworkAPI:status"); + $.ajax({ + url: _wifiboxURL + "/network/status", + type: "GET", + dataType: 'json', + timeout: _timeoutTime, + success: function(response){ + //console.log("NetworkAPI:status response: ",response); + if(response.status == "error" || response.status == "fail") { + if(failedHandler) failedHandler(response); + } else { + completeHandler(response.data); + } + } + }).fail(function() { + if(failedHandler) failedHandler(); + }); + }; + + this.associate = function(ssid,phrase,recreate) { + //console.log("NetworkAPI:associate"); + var postData = { + ssid:ssid, + phrase:phrase, + recreate:recreate + }; + $.ajax({ + url: _wifiboxCGIBinURL + "/network/associate", + type: "POST", + data: postData, + dataType: 'json', + timeout: _timeoutTime, + success: function(response){ + //console.log("NetworkAPI:associate response: ",response); + } + }).fail(function() { + //console.log("NetworkAPI:associate: timeout (normal behavior)"); + }); + }; + + this.openAP = function() { + //console.log("NetworkAPI:openAP"); + $.ajax({ + url: _wifiboxCGIBinURL + "/network/openap", + type: "POST", + dataType: 'json', + timeout: _timeoutTime, + success: function(response){ + //console.log("NetworkAPI:openAP response: ",response); + } + }).fail(function() { + //console.log("NetworkAPI:openAP: timeout (normal behavior)"); + }); + }; + + this.signin = function() { + $.ajax({ + url: _wifiboxCGIBinURL + "/network/signin", + type: "GET", + dataType: 'json', + timeout: _timeoutTime, + success: function(response){ + //console.log("NetworkAPI:signin response: ",response); + } + }).fail(function() { + //console.log("NetworkAPI:signin: failed"); + }); + }; + + this.alive = function(wifiboxURL,timeoutTime,completeHandler,failedHandler) { + if(wifiboxURL.indexOf("http://") != 0) { + wifiboxURL = "http://" + wifiboxURL; + } + timeoutTime = (timeoutTime == -1)? _timeoutTime : timeoutTime; + ///console.log("NetworkAPI:alive: ",wifiboxURL); + $.ajax({ + url: wifiboxURL + _apiPath + "/network/alive", + type: "GET", + dataType: 'json', + timeout: timeoutTime, + success: function(response){ + //console.log("NetworkAPI:alive response: ",response); + if(response.status == "error" || response.status == "fail") { + if(failedHandler) failedHandler(response); + } else { + completeHandler(response.data); + } + } + }).fail(function() { + //console.log("NetworkAPI:alive failed"); + if(failedHandler) failedHandler(); + }); + }; +} \ No newline at end of file diff --git a/js/main.js b/js/main.js index a91c833..20d2eeb 100644 --- a/js/main.js +++ b/js/main.js @@ -1,4 +1,10 @@ - +/* + * This file is part of the Doodle3D project (http://doodle3d.com). + * + * Copyright (c) 2013, Doodle3D + * This software is licensed under the terms of the GNU GPL v2 or later. + * See file LICENSE.txt or visit http://www.gnu.org/licenses/gpl.html for full license details. + */ var retrieveListInterval = 3000; var retrieveListDelay; // retry setTimout instance var boxTimeoutTime = 500; @@ -7,7 +13,7 @@ var numBoxesChecking = 0; // count how many boxes we are checking var numBoxesFound = 0; // count how many boxes responded var connectedBox = {localip:"192.168.5.1",wifiboxid:"Wired WiFi-Box"}; -var apBox = {localip:"draw.doodle3d.com",wifiboxid:"WiFi-Box"}; +var apBox = {localip:"192.168.10.1",wifiboxid:"WiFi-Box",link:"http://draw.doodle3d.com"}; var connectAPI = "http://connect.doodle3d.com/api" var boxAPI = "http://draw.doodle3d.com/d3dapi"; @@ -17,11 +23,19 @@ var $hint; var $preloader; var spinner; +var boxes = {}; + +var networkAPI = new NetworkAPI(); +var connectAPI = new ConnectAPI(); + $(function() { // console.log("ready"); - + + networkAPI.init(); + $intro = $("#intro"); $list = $("#list"); + $hint = $("#hint"); $preloader = $("#preloader"); @@ -47,107 +61,97 @@ $(function() { spinner.spin($preloader[0]); retrieveList(); - - // DEBUG -// numBoxesFound = 4; -// updateIntro(); }); function retrieveList() { $preloader.show(); //spinner.spin($preloader[0]); - - $.ajax({ - timeout: 2000, - url: connectAPI+"/list.php", - dataType: 'json', - success: function(response){ - //console.log("retrieveList response: ",response); - if(response.status == "success") { - var foundBoxes = response.data; - foundBoxes.push(connectedBox); - updateList(foundBoxes); - } - clearTimeout(retrieveListDelay); - retrieveListDelay = setTimeout(retrieveList, retrieveListInterval); - } - }).fail(function() { - console.log("retrieveList: failed"); - + connectAPI.list(function(foundBoxes) { + //console.log(" foundBoxes: ",foundBoxes); + foundBoxes.push(connectedBox); + updateList(foundBoxes); + clearTimeout(retrieveListDelay); + retrieveListDelay = setTimeout(retrieveList, retrieveListInterval); + removeBox(apBox.localip,true); + }, function() { // if web is not accessible try to find the box as an accesspoint // if not found, we look for a wired box - checkBox(apBox, function(alive) { - if(alive) updateList([apBox]); - else updateList([connectedBox]); - }); + networkAPI.alive(apBox.localip,boxTimeoutTime,function() { + console.log("found apBox"); + updateList([apBox]); + }, function() { + console.log("not found apBox"); + updateList([connectedBox]); + }); clearTimeout(retrieveListDelay); retrieveListDelay = setTimeout(retrieveList, retrieveListInterval); // retry after delay }); } -function updateList(boxes) { +function updateList(foundBoxes) { + //console.log("updateList"); numBoxesChecking = 0; numBoxesFound = 0; if (boxes===undefined) boxes = []; - // remove displayed, but unlisted boxes - $list.find("a").each(function(index, element) { - var localip = $(element).attr("id"); - var wifiboxid = $(element).text(); + // remove displayed, but not found boxes + jQuery.each(boxes, function (index,box) { var found = false; - jQuery.each(boxes, function (index,box) { - if(box.localip == localip && box.wifiboxid == wifiboxid) found = true; + jQuery.each(foundBoxes, function (index,foundBox) { + if(foundBox.localip == box.localip && + foundBox.wifiboxid == box.wifiboxid) found = true; }); - if(!found) $(element).parent().remove(); + if(!found) removeBox(box.localip); }) - jQuery.each(boxes, function (index,box) { - checkBox(box); + // check if all found boxes are alive + jQuery.each(foundBoxes, function (index,foundBox) { + checkBox(foundBox); }); - //checkBox(connectedBox); + updateIntro(); } -function checkBox(box,checked) { +function checkBox(boxData) { + //console.log(" checkBox: ",boxData.localip); numBoxesChecking++; - $.ajax({ - url: "http://"+box.localip+"/d3dapi/network/alive", - dataType: "json", - timeout: boxTimeoutTime, - success: function(response){ - var alive = (response.status == "success"); - if(alive) { - numBoxesFound++; - addBox(box); - } else { - removeBox(box); - } - numBoxesChecking--; - updateIntro(); - if(checked) checked(alive); - } - }).fail(function() { - //console.log("box not alive: "+box.wifiboxid); + + networkAPI.alive(boxData.localip,boxTimeoutTime,function() { + addBox(boxData); + numBoxesFound++; + numBoxesChecking--; + updateIntro(); + }, function() { + removeBox(boxData.localip); numBoxesChecking--; - removeBox(box); updateIntro(); - if(checked) checked(false); }); } - -function addBox(box) { - if(boxExists(box.localip)) return; - var url = "http://"+box.localip; - var element = "
  • "+box.wifiboxid+"
  • "; - $(element).hide().appendTo($list).fadeIn(500); +function getBox(localip) { + return boxes[localip]; } -function boxExists(localip){ - return $list.find("a[id|='"+localip+"']").length > 0; +function addBox(boxData) { + if(getBox(boxData.localip) !== undefined) return; + //console.log("addBox: ",boxData.localip); + var box = new Box(); + box.init(boxData,$list); + box.destroyedHandler = boxDestroyedHandler; + boxes[box.localip] = box; + + //createBox(boxData); } -function removeBox(box) { - var $element = $list.find("a[id|='"+box.localip+"']"); - $element.remove(); +function removeBox(localip,force) { + var box = getBox(localip); + if(box === undefined) return; + //console.log("removeBox: ",localip," force: ",force); + if(!force && box.connecting) return; + //console.log(" calling destroyed"); + box.destroy(); +} +function boxDestroyedHandler(box) { + //console.log("boxDestroyedHandler"); + delete boxes[box.localip]; } function updateIntro() { @@ -162,4 +166,33 @@ function updateIntro() { } $preloader.fadeOut(1000); } -} \ No newline at end of file +} + +/*function createBox(boxData) { + //console.log("createBox: ",box.localip,box.wifiboxid); + var url = "http://"+box.localip; + var element = $("
  • "); + element.data("wifiboxid",box.wifiboxid); + element.append(""+box.wifiboxid+""); + + var networkPanelElement = $("#networkForm").clone(); + networkPanelElement.addClass(networkPanelElement.attr("id")); + networkPanelElement.removeAttr("id"); + element.append(networkPanelElement); + + var networkPanel = new NetworkPanel(); + networkPanel.id = box.localip; + networkPanel.init(url,networkPanelElement, function(networkStatus) { + element.toggleClass("complex",(networkStatus != NetworkAPI.STATUS.CONNECTED)); + element.toggleClass("connecting",(networkStatus == NetworkAPI.STATUS.CONNECTING)); + console.log("status changed: ",networkStatus); + //console.log(" url: ",url); + if(networkStatus == NetworkAPI.STATUS.CONNECTING) { + setTimeout(function() { + console.log("delayed remove"); + removeBox(box,true); + }, 10000); + } + }); + return element; +}*/ \ No newline at end of file