0
0
mirror of https://github.com/Doodle3D/doodle3d-connect.git synced 2024-12-25 18:13:48 +01:00

Guiding users to connect box to WiFi network

This commit is contained in:
peteruithoven 2014-02-24 11:26:30 +01:00
parent 4fb58d0878
commit abbbcc17e9
7 changed files with 811 additions and 94 deletions

View File

@ -30,17 +30,20 @@ a {
#list { #list {
padding: 0; padding: 0;
} }
#list li {
.box{
list-style-type: none; list-style-type: none;
float: left; float: left;
}
#list a {
margin: 0 15px 15px 0;
padding: 25px 0 0 0;
display: block;
width: 200px; margin: 0 15px 15px 0;
height: 175px; /*padding: 25px;*/
padding: 0 0 25px 0;
display: block;
position: relative;
min-width: 200px; /*175px;*/
min-height: 175px; /*175px;*/
/*height: 275px;*/
border: 2px solid #333; border: 2px solid #333;
border-radius: 25px; border-radius: 25px;
@ -49,28 +52,118 @@ a {
-webkit-box-shadow: 0px 2px 7px 0px rgba(16, 16, 16, 0.60); -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); 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; transition:background-color 0.1s, color 0.1s;
} }
#list a:hover { .box:hover {
background-color: #5491D2; background-color: #5491D2;
}
.box:hover a{
color: #fff; 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 { #hint {
display:none; display:none;
position: absolute; position: absolute;
bottom: 1em; bottom: 1em;
line-height: 1.5;
} }
/*.vertImage {*/ #networkForm {
/*margin: 0;*/ display: none;
/*padding: 0;*/ }
/*border: 2px solid #f0f;*/ .box .networkForm {
/*max-width: 100%;*/ display: none;
/*height: auto;*/ }
/*width: auto; *//* for ie9 */ .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;
}

View File

@ -18,6 +18,10 @@
<script src="js/libs/jquery-1.8.3.min.js" type="text/javascript"></script> <script src="js/libs/jquery-1.8.3.min.js" type="text/javascript"></script>
<script src="js/libs/spin.min.js" type="text/javascript"></script> <script src="js/libs/spin.min.js" type="text/javascript"></script>
<script src="js/api/NetworkAPI.js" type="text/javascript"></script>
<script src="js/api/ConnectAPI.js" type="text/javascript"></script>
<script src="js/NetworkPanel.js" type="text/javascript"></script>
<script src="js/Box.js" type="text/javascript"></script>
<script src="js/main.js" type="text/javascript"></script> <script src="js/main.js" type="text/javascript"></script>
</head> </head>
<body> <body>
@ -38,7 +42,7 @@
<ul id="list" class="cf"></ul> <ul id="list" class="cf"></ul>
<small id="hint"> <small id="hint">
Can&#8217;t find your box? <br/> Can&#8217;t find your box? <br/>
Maybe the box isn&#8217;t connected to your network yet, try to connect to a Doodle3D-... WiFi network. <br/> Maybe your box isn&#8217;t connected to your network yet, try to connect to a Doodle3D-... WiFi network. <br/>
Otherwise, make sure you&#8217;re on the same WiFi network. <br/> Otherwise, make sure you&#8217;re on the same WiFi network. <br/>
You can always connect your box to your computer using an ethernet cable. You can always connect your box to your computer using an ethernet cable.
</small> </small>
@ -49,5 +53,24 @@
</div> </div>
</div> </div>
<form id="networkForm">
<p>Connect box to your WiFi network:</p>
<label for="ssid">Network:</label><input type="text" name="ssid" id="ssid"><input type="button" name="list" value="List" class="button" id="listNetworks"/>
<select id="network" name=""></select><input type="button" name="refresh" value="Refresh" class="button" id="refreshNetworks"/><br/>
<div id="passwordSettings">
<div>
<label for="phrase" id="phraseLabel">Password:</label>
</div>
<div>
<input type="password" name="" id="phrase"><br/>
<input id="showPassword" type="checkbox" name="showPassword" value="showPassword">
<label for="showPassword" id="showPasswordLabel" class="inline">show password</label>
</div>
</div>
<br/>
<input type="button" value="Connect" class="button" id="btnConnect"/>
<span id="statusText"></span><br/>
</form>
</body> </body>
</html> </html>

78
js/Box.js Normal file
View File

@ -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 = $("<li id='"+_self.localip+"' class='box'></li>");
_element.append("<a href='"+link+"'>"+_self.wifiboxid+"</a>");
_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);
}
}

304
js/NetworkPanel.js Normal file
View File

@ -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: <b>"+_currentNetwork+"</b>.";
break;
case NetworkAPI.STATUS.CONNECTING:
msg = "Connecting... ";
var targetNetwork;
if(_selectedNetwork != undefined) {
targetNetwork = _selectedNetwork;
} else if(_currentNetwork != undefined) {
targetNetwork = _currentNetwork;
}
if(targetNetwork != undefined) {
msg += "<br/>Connect your device to <b>"+targetNetwork+"</b>.";
}
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(
$("<option></option>").val(NETWORK_SELECTOR_DEFAULT).html(NETWORK_SELECTOR_DEFAULT)
);
$.each(networks, function(index,network) {
if(network.ssid == _currentNetwork) {
foundCurrentNetwork = true;
}
_networkSelector.append(
$("<option></option>").val(network.ssid).html(network.ssid)
);
});
/*_networkSelector.append(
$("<option></option>").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);
}
}

36
js/api/ConnectAPI.js Normal file
View File

@ -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();
});
};
}

150
js/api/NetworkAPI.js Normal file
View File

@ -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();
});
};
}

View File

@ -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 retrieveListInterval = 3000;
var retrieveListDelay; // retry setTimout instance var retrieveListDelay; // retry setTimout instance
var boxTimeoutTime = 500; 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 numBoxesFound = 0; // count how many boxes responded
var connectedBox = {localip:"192.168.5.1",wifiboxid:"Wired WiFi-Box"}; 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 connectAPI = "http://connect.doodle3d.com/api"
var boxAPI = "http://draw.doodle3d.com/d3dapi"; var boxAPI = "http://draw.doodle3d.com/d3dapi";
@ -17,11 +23,19 @@ var $hint;
var $preloader; var $preloader;
var spinner; var spinner;
var boxes = {};
var networkAPI = new NetworkAPI();
var connectAPI = new ConnectAPI();
$(function() { $(function() {
// console.log("ready"); // console.log("ready");
networkAPI.init();
$intro = $("#intro"); $intro = $("#intro");
$list = $("#list"); $list = $("#list");
$hint = $("#hint"); $hint = $("#hint");
$preloader = $("#preloader"); $preloader = $("#preloader");
@ -47,107 +61,97 @@ $(function() {
spinner.spin($preloader[0]); spinner.spin($preloader[0]);
retrieveList(); retrieveList();
// DEBUG
// numBoxesFound = 4;
// updateIntro();
}); });
function retrieveList() { function retrieveList() {
$preloader.show(); $preloader.show();
//spinner.spin($preloader[0]); //spinner.spin($preloader[0]);
connectAPI.list(function(foundBoxes) {
$.ajax({ //console.log(" foundBoxes: ",foundBoxes);
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); foundBoxes.push(connectedBox);
updateList(foundBoxes); updateList(foundBoxes);
}
clearTimeout(retrieveListDelay); clearTimeout(retrieveListDelay);
retrieveListDelay = setTimeout(retrieveList, retrieveListInterval); retrieveListDelay = setTimeout(retrieveList, retrieveListInterval);
} removeBox(apBox.localip,true);
}).fail(function() { }, function() {
console.log("retrieveList: failed");
// if web is not accessible try to find the box as an accesspoint // if web is not accessible try to find the box as an accesspoint
// if not found, we look for a wired box // if not found, we look for a wired box
checkBox(apBox, function(alive) { networkAPI.alive(apBox.localip,boxTimeoutTime,function() {
if(alive) updateList([apBox]); console.log("found apBox");
else updateList([connectedBox]); updateList([apBox]);
}, function() {
console.log("not found apBox");
updateList([connectedBox]);
}); });
clearTimeout(retrieveListDelay); clearTimeout(retrieveListDelay);
retrieveListDelay = setTimeout(retrieveList, retrieveListInterval); // retry after delay retrieveListDelay = setTimeout(retrieveList, retrieveListInterval); // retry after delay
}); });
} }
function updateList(boxes) { function updateList(foundBoxes) {
//console.log("updateList");
numBoxesChecking = 0; numBoxesChecking = 0;
numBoxesFound = 0; numBoxesFound = 0;
if (boxes===undefined) boxes = []; if (boxes===undefined) boxes = [];
// remove displayed, but unlisted boxes // remove displayed, but not found boxes
$list.find("a").each(function(index, element) {
var localip = $(element).attr("id");
var wifiboxid = $(element).text();
var found = false;
jQuery.each(boxes, function (index,box) { jQuery.each(boxes, function (index,box) {
if(box.localip == localip && box.wifiboxid == wifiboxid) found = true; var found = false;
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) { // check if all found boxes are alive
checkBox(box); jQuery.each(foundBoxes, function (index,foundBox) {
checkBox(foundBox);
}); });
//checkBox(connectedBox);
updateIntro(); updateIntro();
} }
function checkBox(box,checked) { function checkBox(boxData) {
//console.log(" checkBox: ",boxData.localip);
numBoxesChecking++; numBoxesChecking++;
$.ajax({
url: "http://"+box.localip+"/d3dapi/network/alive", networkAPI.alive(boxData.localip,boxTimeoutTime,function() {
dataType: "json", addBox(boxData);
timeout: boxTimeoutTime,
success: function(response){
var alive = (response.status == "success");
if(alive) {
numBoxesFound++; numBoxesFound++;
addBox(box);
} else {
removeBox(box);
}
numBoxesChecking--; numBoxesChecking--;
updateIntro(); updateIntro();
if(checked) checked(alive); }, function() {
} removeBox(boxData.localip);
}).fail(function() {
//console.log("box not alive: "+box.wifiboxid);
numBoxesChecking--; numBoxesChecking--;
removeBox(box);
updateIntro(); updateIntro();
if(checked) checked(false);
}); });
} }
function getBox(localip) {
return boxes[localip];
}
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;
function addBox(box) { //createBox(boxData);
if(boxExists(box.localip)) return;
var url = "http://"+box.localip;
var element = "<li><a href='"+url+"' id='"+box.localip+"'>"+box.wifiboxid+"</a></li>";
$(element).hide().appendTo($list).fadeIn(500);
} }
function boxExists(localip){ function removeBox(localip,force) {
return $list.find("a[id|='"+localip+"']").length > 0; 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 removeBox(box) { function boxDestroyedHandler(box) {
var $element = $list.find("a[id|='"+box.localip+"']"); //console.log("boxDestroyedHandler");
$element.remove(); delete boxes[box.localip];
} }
function updateIntro() { function updateIntro() {
@ -163,3 +167,32 @@ function updateIntro() {
$preloader.fadeOut(1000); $preloader.fadeOut(1000);
} }
} }
/*function createBox(boxData) {
//console.log("createBox: ",box.localip,box.wifiboxid);
var url = "http://"+box.localip;
var element = $("<li id='"+box.localip+"' class='box'></li>");
element.data("wifiboxid",box.wifiboxid);
element.append("<a href='"+((box.url)? box.url : url)+"'>"+box.wifiboxid+"</a>");
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;
}*/