UNPKG

stlive

Version:

Live edit your JS/HTML/CSS source code in Sencha Touch / PhoneGap projects. Autosync changes to multiple mobile devices of mixed OS types. Massively speed up your mobile app development by avoiding most compiling and redeployment.

375 lines (322 loc) 10.6 kB
(function() { /*--------------------------------------------------- Globals ---------------------------------------------------*/ var config = {}; /*--------------------------------------------------- General ---------------------------------------------------*/ $().ready(function() { // Add events $('#login-form').submit(buildSubmit); $('a[target="_system"]').on('click', function(e) { e.preventDefault(); window.open($(this).attr('href'), '_system'); }); // Issue #27 // When input box is selected, the soft-keyboard is shown // but the input box focus is in the incorrect position. $('#address').on('touchstart', function() { $('#address').focus(); }); // On input selection, backup the current address. $('#address').on('focus', function() { $('#address').attr('currentValue', getAddressField()); }); // On input de-selection, restore backup if there is no content. $('#address').on('blur', function() { var $address = $('#address'), whitespaceRegex = /^\s*$/; if (whitespaceRegex.test(getAddressField())) { $address.val($address.attr('currentValue')); } $address.attr('currentValue', ''); }); $('#qrcode').on('click', function(e) { e.preventDefault(); cordova.plugins.barcodeScanner.scan(function (result) { /*alert("We got a barcode\n" + "Result: " + result.text + "\n" + "Format: " + result.format + "\n" + "Cancelled: " + result.cancelled);*/ if (!result.cancelled) { var $address = $('#address'); $address.val(result.text); buildSubmit(); } }, function (error) { alert("Scanning failed: " + error); }); }); // Work around CSS browser issues. supportBrowserQuirks(); }); $(document).on('deviceready', function() { // Add slight delay to allow DOM rendering to finish. // Avoids flicker on slower devices. setTimeout(function() { // allow the screen to dim when returning from the served app window.plugins.insomnia.allowSleepAgain(); navigator.splashscreen.hide(); $('.footer').removeClass('faded'); // Load configuration loadConfig(function() { setTimeout( function() { $('.alert').removeClass('alert'); $('.visor').removeClass('pulse'); $('.visor label').html('Hi!'); $('.visor .eye').removeClass('faded'); }, 1750); setTimeout( openBot, 2750); setTimeout( function() { $('.visor .eye').addClass('hidden'); }, 3350 ); }); }, 350); }); /*--------------------------------------------------- App - Configuration ---------------------------------------------------*/ function loadConfig(callback) { readFile('config.json', function(e, text) { config = parseAsJSON(text); // load defaults config.address = config.address || '127.0.0.1:3000'; // load server address if (config.address) { $('#address').val(config.address); } callback(); }); } function saveConfig(callback) { // this URL config.URL = document.URL; // server address config.address = getAddressField(); // save config saveFile('config.json', config, function(e) { callback(); }); } function readFile(filepath, callback) { window.requestFileSystem( LocalFileSystem.PERSISTENT, 0, function(fileSystem) { fileSystem.root.getFile( filepath, null, function gotFileEntry(fileEntry) { fileEntry.file( function gotFile(file){ var reader = new FileReader(); reader.onloadend = function(evt) { // #72 - Fix WP8 loading of config.json // On WP8, `evt.target.result` is returned as an object instead // of a string. Since WP8 is using a newer version of the File API // this may be a platform quirk or an API update. var text = evt.target.result; text = (typeof text === 'object') ? JSON.stringify(text) : text; callback(null, text); // text is a string }; reader.readAsText(file); }, function(error) { callback(error); } ); }, function(error) { callback(error); } ); }, function(error) { callback(error); } ); } function saveFile(filepath, data, callback) { data = (typeof data === 'string') ? data : JSON.stringify(data); window.requestFileSystem( LocalFileSystem.PERSISTENT, 0, function(fileSystem) { fileSystem.root.getFile( filepath, { create: true, exclusive: false }, function(fileEntry) { fileEntry.createWriter( function(writer) { writer.onwriteend = function(evt) { callback(); }; writer.write(data); }, function(e) { callback(e); } ); }, function(e) { callback(e); } ); }, function(e) { callback(e); } ); } function parseAsJSON(text) { try { return JSON.parse(text); } catch(e) { return {}; } } /*--------------------------------------------------- UI - General ---------------------------------------------------*/ function openBot() { $('.monitor form').removeClass('hidden'); setTimeout( function() { $('.panel.top').addClass('open'); $('.visor').addClass('fade-out'); $('.monitor form').removeClass('faded'); setTimeout( function() { $('.visor').addClass('hidden'); }, 550); }, 50); } function closeBot() { $('.visor').removeClass('hidden'); setTimeout( function() { $('.panel.top').removeClass('open'); $('.visor').removeClass('fade-out'); $('.monitor form').addClass('faded'); setTimeout( function() { $('.monitor form').addClass('hidden'); }, 550); }, 50); } // Note that the bot needs to be closed to be able to view this function updateMessage( msg ) { $('.visor').removeClass('pulse'); $('.visor label').html( msg.toUpperCase() ); } function errorMessage( msg ) { updateMessage( msg ); $('.visor').removeClass('pulse'); $('.monitor').addClass('alert'); } function pulsingMessage( msg ) { updateMessage( msg ); $('.visor').addClass('pulse'); } /*--------------------------------------------------- UI - Form ---------------------------------------------------*/ function buildSubmit() { closeBot(); updateMessage(''); setTimeout(function() { pulsingMessage( 'Connecting...' ); registerWithServer(); }, 500); // Placeholder //setTimeout(onBuildSubmitError,2000); return false; } function onBuildSubmitSuccess() { updateMessage( 'Success!' ); saveConfig(function() { // don't allow the screen to dim when serving an app window.plugins.insomnia.keepAwake(); setTimeout( function() { window.location = getAddress(); }, 1000 ); }); } function onBuildSubmitError(message) { errorMessage('Error!'); setTimeout(function() { errorMessage('Timed out!'); }, 1500); setTimeout(function() { $('.monitor').removeClass('alert'); updateMessage(''); openBot(); }, 3500); } function registerWithServer() { $.ajax({ type: 'POST', url: getAddress('/__api__/register'), dataType: 'json', data: { platform: device.platform, version: device.cordova }, timeout: 1000 * 10, success: function(data) { onBuildSubmitSuccess(); }, error: function(xhr, type) { // support older servers that do not support /register $.ajax({ type: 'GET', url: getAddress(), dataType: 'text', timeout: 1000 * 10, success: function(data) { onBuildSubmitSuccess(); }, error: function(xhr, type) { onBuildSubmitError(); } }); } }); } function getAddressField() { var $address = $('#address'), address = $address.val() || $address.attr('placeholder'); return address; } function getAddress(path) { var address = getAddressField(); // default to http:// when no protocol exists address = (address.match(/^(.*:\/\/)/)) ? address : 'http://' + address; // append an optional path if (path) { address += '/' + path; // replace double forward slashes with a single forward-slash // except after the protocol (://) address = address.replace(/([^:])\/\//g, '$1/'); } return address; } /*--------------------------------------------------- Browser - Quirks ---------------------------------------------------*/ function supportBrowserQuirks() { // Issue #51 // Windows Phone 8 does not support border-image if (/IEMobile\/10/.test(window.navigator.userAgent)) { var element = document.createElement('style'); element.setAttribute('type', 'text/css'); element.innerHTML = [ '#bot .monitor .cover {', ' background-image: url(img/frame.png);', ' background-size: 270px 220px;', ' background-repeat: no-repeat;', ' border: none;', '}' ].join('\n'); document.body.appendChild(element); } } })();