/* * app.shell.js * Shell module for SPA */ /*jslint browser : true, continue : true, devel : true, indent : 2, maxerr : 50, newcap : true, nomen : true, plusplus : true, regexp : true, sloppy : true, vars : false, white : true */ /*global $, app */ app.shell = (function () { 'use strict'; //---------------- BEGIN MODULE SCOPE VARIABLES -------------- var stateMap = { $container: undefined, anchor_map: {}, user: { authenticated: false, token: '', name: '', id:0 }, apiUrl: '', search_cache: { has_cache: false } }, tokenExpired, //onUPdate, onLogin, onLogout, onShowError, onClearError, initModule; //----------------- END MODULE SCOPE VARIABLES --------------- //------------------- BEGIN UTILITY METHODS ------------------ tokenExpired = function () { //fetch stored creds if available var creds = store.get('pecklist.usercreds'); if (creds) { //check if token has expired //is the date greater than the expires date var rightNowUtc = new Date(); var expDate = new Date(creds.expires * 1000); if (rightNowUtc > expDate) { return true; } else { return false; } } else { return true; } } //-------------------- END UTILITY METHODS ------------------- //------------------- BEGIN EVENT HANDLERS ------------------- onLogin = function (event, login_user) { //store creds store.set('pecklist.usercreds', stateMap.user); //New token needs to reset lastNav stateMap.lastNav = new Date(); //Go to the home page page('#!/main/'); return false; }; onLogout = function (event) { store.clear(); stateMap.user.authenticated = false; stateMap.user.name = ''; stateMap.user.token = ''; stateMap.user.id=0; page('#!/authenticate/'); return false; }; // onUpdate = function (event) { // window.location.reload(true); // return false; // }; onShowError = function (event, msg) { $("#app-error-div").removeClass("d-none"); $('#app-error-message').text(msg); return false; }; onClearError = function (event) { $("#app-error-div").addClass("d-none"); return false; }; //-------------------- END EVENT HANDLERS -------------------- //------------------- BEGIN PUBLIC METHODS ------------------- initModule = function ($container) { document.title = 'Pecklist ' + app.api.GZAppVersion; //PRE FLIGHT CHECK //================ //local storage required if (!store.enabled) { alert('Local storage is not supported by your browser. Please disable "Private Mode", or upgrade to a modern browser.'); return; } //wait indicator for ajax functions $(document).ajaxStart(function () { //disable all buttons $('.app-frm-buttons button').prop('disabled', true).addClass('disabled'); //$('.app-frm-buttons button').attr('disabled', 'disabled'); $("body").css("cursor", "progress"); //add app-ajax-busy style to buttons div where user clicked $('.app-frm-buttons').addClass('app-ajax-busy'); }).ajaxStop(function () { //with delay in case it's too fast to see setTimeout(function () { $('.app-frm-buttons button').prop('disabled', false).removeClass('disabled'); //$('.app-frm-buttons button').removeAttr('disabled'); $("body").css("cursor", "default"); $('.app-frm-buttons').removeClass('app-ajax-busy'); }, 250); }); // load HTML and map jQuery collections stateMap.$container = $container; $container.html(Handlebars.templates['app.shell']({})); //auto hide navbar on click of nav link item $('.nav-link').on('click',function() { $('.navbar-collapse').collapse('hide'); }); //determine API url and save it stateMap.apiUrl = app.utilB.getApiUrl(); //fetch stored creds if available var creds = store.get('pecklist.usercreds'); //check if token has expired if (tokenExpired()) { stateMap.user.authenticated = false; stateMap.user.name = ''; stateMap.user.token = ''; stateMap.user.id=0; } else { //Show the logout item in the menu $(".app-mnu-logout").removeClass("app-hidden"); stateMap.user.authenticated = true; stateMap.user.name = creds.name; stateMap.user.token = creds.token; stateMap.user.dlkey=creds.dlkey; stateMap.user.id=creds.id; } //} //EVENT SUBSCRIPTIONS $.gevent.subscribe($container, 'app-login', onLogin); $.gevent.subscribe($container, 'app-logout', onLogout); //$.gevent.subscribe($container, 'gz-update', onUpdate); $.gevent.subscribe($container, 'app-show-error', onShowError); $.gevent.subscribe($container, 'app-clear-error', onClearError); //ROUTES // page.base('/index.html'); page('*', beforeUrlChange); page('/authenticate', authenticate); page('/', main); page('/logout', function () { $.gevent.publish('app-logout'); }); page('/main', main); page('/settings', settings); page('*', notFound); page({ hashbang: true }); // /ROUTES }; // End PUBLIC method /initModule/ var beforeUrlChange = function (ctx, next) { $.gevent.publish('app-clear-error'); app.shell.stateMap.mediaSize = app.utilB.getMediaSize(); //bypass stuff below if about to logout if (ctx.path == '/logout') { return next(); } //================================================================ //Check authentication token to see if expired, but only if it's been a few minutes since last navigation if (stateMap.user.authenticated) { //This first bit sets the last nav in cases where it's never been set before //default to one hour ago in case it hasn't ever been set yet or isn't in statemap if (!stateMap.lastNav) { //Isn't this sketchy? Is this a date or a moment being set here stateMap.lastNav = moment().subtract(3600, 's').toDate();//60 minutes ago } var mNow = moment(new Date()); //todays date var mLastNav = moment(stateMap.lastNav); // another date var duration = moment.duration(mNow.diff(mLastNav)); var secondsSinceLastNav = duration.asSeconds(); if (secondsSinceLastNav > 300)//have we checked in the last 5 minutes? { if (tokenExpired()) { stateMap.user.authenticated = false; } } stateMap.lastNav = new Date(); } //=============================================================== //Not logged in and trying to go somewhere but authenticate? if (!stateMap.user.authenticated) { //hide nav $("#gz-nav").hide({ duration: 200 }); //page nav to authenticate if (ctx.path != '/authenticate/') return page('#!/authenticate/'); } else { //logged in so make sure to show toolbar here $("#gz-nav").show({ duration: 200 }); } next(); } var authenticate = function (ctx) { app.authenticate.configModule({ context: ctx }); app.authenticate.initModule(); } var main = function (ctx) { app.nav.setSelectedMenuItem('main'); app.main.configModule({ context: ctx }); app.main.initModule(); } var settings = function (ctx) { app.nav.setSelectedMenuItem('settings'); app.settings.configModule({ context: ctx }); app.settings.initModule(); } var notFound = function (ctx) { app.fourohfour.configModule({ context: ctx }); app.fourohfour.initModule(); } return { initModule: initModule, stateMap: stateMap }; //------------------- END PUBLIC METHODS --------------------- }());