diff --git a/app/main/controller/api/system.php b/app/main/controller/api/system.php index f94ebf64..bb80eed5 100644 --- a/app/main/controller/api/system.php +++ b/app/main/controller/api/system.php @@ -173,6 +173,9 @@ class System extends Controller\AccessController { if($cacheSystem){ $f3->set($cacheKey, $graphData, $ttl); } + }else{ + // server cache data exists -> client should cache as well + $cacheResponse = true; } $graphsData[$systemId] = $graphData; } diff --git a/app/main/controller/controller.php b/app/main/controller/controller.php index 0f785c74..8e09414b 100644 --- a/app/main/controller/controller.php +++ b/app/main/controller/controller.php @@ -76,7 +76,12 @@ class Controller { $this->initSession($f3); if($f3->get('AJAX')){ - header('Content-type: application/json'); + header('Content-Type: application/json'); + + // send "maintenance" Header -> e.g. before server update + if($modeMaintenance = (int)Config::getPathfinderData('login.mode_maintenance')){ + header('Pf-Maintenance: ' . $modeMaintenance); + } }else{ $this->initResource($f3); diff --git a/app/main/lib/logging/handler/AbstractSlackWebhookHandler.php b/app/main/lib/logging/handler/AbstractSlackWebhookHandler.php index 0a2fbab3..756fb37a 100644 --- a/app/main/lib/logging/handler/AbstractSlackWebhookHandler.php +++ b/app/main/lib/logging/handler/AbstractSlackWebhookHandler.php @@ -141,7 +141,7 @@ abstract class AbstractSlackWebhookHandler extends Handler\AbstractProcessingHan CURLOPT_URL => $this->webhookUrl, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, - CURLOPT_HTTPHEADER => ['Content-type: application/json'], + CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_POSTFIELDS => $postString ]; if (defined('CURLOPT_SAFE_UPLOAD')) { diff --git a/js/app/mappage.js b/js/app/mappage.js index 2d5be008..f006d451 100644 --- a/js/app/mappage.js +++ b/js/app/mappage.js @@ -39,7 +39,6 @@ define([ Util.initDefaultEditableConfig(); // load page - // load info (maintenance) info panel (if scheduled) $('body').loadPageStructure().setGlobalShortcuts(); // show app information in browser console @@ -203,11 +202,6 @@ define([ // init map module mapModule.initMapModule(); - // load info (maintenance) info panel (if scheduled) - if(Init.programMode.maintenance){ - $('body').showGlobalInfoPanel(); - } - resolve({ action: 'initMapModule', data: false diff --git a/js/app/page.js b/js/app/page.js index 89c2cffb..f7e91be7 100644 --- a/js/app/page.js +++ b/js/app/page.js @@ -58,9 +58,7 @@ define([ headProgramStatusClass: 'pf-head-program-status', // class for "program status" notification // footer - pageFooterId: 'pf-footer', // id for page footer footerLicenceLinkClass: 'pf-footer-licence', // class for "licence" link - globalInfoPanelId: 'pf-global-info', // id for "global info panel" // menu menuHeadMenuLogoClass: 'pf-head-menu-logo', // class for main menu logo @@ -582,7 +580,7 @@ define([ let pageElement = $(this); let moduleData = { - id: config.pageFooterId, + id: Util.config.footerId, footerLicenceLinkClass: config.footerLicenceLinkClass, currentYear: new Date().getFullYear() }; @@ -1263,25 +1261,6 @@ define([ } }; - /** - * show information panel to active users (on bottom) - * @returns {*|jQuery|HTMLElement} - */ - $.fn.showGlobalInfoPanel = function(){ - let body = $(this); - let infoTemplate = 'text!templates/ui/info_panel.html'; - - requirejs([infoTemplate, 'mustache'], function(template, Mustache){ - let data = { - id: config.globalInfoPanelId - }; - let content = $( Mustache.render(template, data) ); - content.insertBefore('#' + config.pageFooterId ); - }); - - return body; - }; - /** * get all form Values as object * this includes all xEditable fields @@ -1331,5 +1310,4 @@ define([ initMapContextMenus: initMapContextMenus }; - }); \ No newline at end of file diff --git a/js/app/util.js b/js/app/util.js index 674f2e90..47e005be 100644 --- a/js/app/util.js +++ b/js/app/util.js @@ -43,6 +43,10 @@ define([ menuButtonCompactId: 'pf-menu-button-compact', // id for menu button "compact" UI map view menuButtonMapDeleteId: 'pf-menu-button-map-delete', // id for menu button "delete map" + // footer + footerId: 'pf-footer', // id for page footer + globalInfoPanelId: 'pf-global-info', // id for "global info panel" + settingsMessageVelocityOptions: { duration: 180 }, @@ -212,33 +216,6 @@ define([ }); }; - /** - * request a captcha image - * @param reason - * @param callback - */ - let getCaptchaImage = function(reason, callback){ - - $.ajax({ - type: 'POST', - url: Init.path.getCaptcha, - data: { - reason: reason - }, - dataType: 'json' - }).done(function(responseData){ - if(responseData.error.length > 0){ - showNotify({title: 'getCaptchaImage', text: 'Captcha image gneration failed', type: 'error'}); - }else{ - callback(responseData.img); - } - }).fail(function(jqXHR, status, error){ - let reason = status + ' ' + error; - showNotify({title: jqXHR.status + ': getCaptchaImage', text: reason, type: 'error'}); - }); - - }; - /** * reset/clear form fields * @returns {*} @@ -855,6 +832,26 @@ define([ }); }; + /** + * get all mapTabElements ( tags) + * or search for a specific tabElement within mapModule + * @param mapId + * @returns {JQuery|*|{}|T} + */ + $.fn.getMapTabElements = function(mapId){ + let mapModule = $(this); + let mapTabElements = mapModule.find('#' + config.mapTabBarId).find('a'); + + if(mapId){ + // search for a specific tab element + mapTabElements = mapTabElements.filter(function(i, el){ + return ( $(el).data('mapId') === mapId ); + }); + } + + return mapTabElements; + }; + /* * =============================================================================================================== * Util functions that are global available for all modules @@ -865,14 +862,14 @@ define([ * get current Pathfinder version number * @returns {*|jQuery} */ - let getVersion = function(){ + let getVersion = () => { return $('body').data('version'); }; /** * show current program version information in browser console */ - let showVersionInfo = function(){ + let showVersionInfo = () => { console.info('PATHFINDER ' + getVersion()); }; @@ -1140,6 +1137,31 @@ define([ '
'; }; + /** + * request a captcha image + * @param reason + * @param callback + */ + let getCaptchaImage = (reason, callback) => { + $.ajax({ + type: 'POST', + url: Init.path.getCaptcha, + data: { + reason: reason + }, + dataType: 'json' + }).done(function(responseData){ + if(responseData.error.length > 0){ + showNotify({title: 'getCaptchaImage', text: 'Captcha image generation failed', type: 'error'}); + }else{ + callback(responseData.img); + } + }).fail(function(jqXHR, status, error){ + let reason = status + ' ' + error; + showNotify({title: jqXHR.status + ': getCaptchaImage', text: reason, type: 'error'}); + }); + }; + /** * get the current main trigger delay for the main trigger functions * optional in/decrease the delay @@ -1237,7 +1259,6 @@ define([ * @param timerName */ let timeStart = timerName => { - if(typeof performance === 'object'){ stopTimerCache[timerName] = performance.now(); }else{ @@ -1251,7 +1272,6 @@ define([ * @returns {number} */ let timeStop = timerName => { - let duration = 0; if( stopTimerCache.hasOwnProperty(timerName) ){ @@ -1324,8 +1344,8 @@ define([ /** * stop browser tab title "blinking" */ - let stopTabBlink = function(){ - requirejs(['notification'], function(Notification){ + let stopTabBlink = () => { + requirejs(['notification'], Notification => { Notification.stopTabBlink(); }); }; @@ -1408,6 +1428,26 @@ define([ return tabId; }; + /** + * show information panel to active users (on bottom) + * @param show + */ + let toggleGlobalInfoPanel = (show = true) => { + let infoPanel = $('#' + config.globalInfoPanelId); + if( show && !infoPanel.length){ + // info panel not already shown + requirejs(['text!templates/ui/info_panel.html', 'mustache'], (template, Mustache) => { + let data = { + id: config.globalInfoPanelId + }; + let content = $(Mustache.render(template, data)); + content.insertBefore('#' + config.footerId); + }); + }else if (!show && infoPanel.length){ + infoPanel.remove(); + } + }; + /** * set default jQuery AJAX configuration */ @@ -1422,8 +1462,13 @@ define([ if(settings.crossDomain === false){ // add current character data to ANY XHR request (HTTP HEADER) // -> This helps to identify multiple characters on multiple browser tabs - jqXHR.setRequestHeader('Pf-Character', getCurrentCharacterId()); + jqXHR.setRequestHeader('pf-character', getCurrentCharacterId()); } + }, + complete: function(jqXHR, textStatus){ + // show "maintenance information panel -> if scheduled + let isMaintenance = parseInt(jqXHR.getResponseHeader('pf-maintenance')) || 0; + toggleGlobalInfoPanel(isMaintenance); } }); }; @@ -1559,26 +1604,6 @@ define([ }); }; - /** - * get all mapTabElements (
tags) - * or search for a specific tabElement within mapModule - * @param mapId - * @returns {JQuery|*|{}|T} - */ - $.fn.getMapTabElements = function(mapId){ - let mapModule = $(this); - let mapTabElements = mapModule.find('#' + config.mapTabBarId).find('a'); - - if(mapId){ - // search for a specific tab element - mapTabElements = mapTabElements.filter(function(i, el){ - return ( $(el).data('mapId') === mapId ); - }); - } - - return mapTabElements; - }; - /** * get mapElement from overlay or any child of that * @param mapOverlay @@ -1896,7 +1921,7 @@ define([ * @param trueSec * @returns {string} */ - let getTrueSecClassForSystem = function(trueSec){ + let getTrueSecClassForSystem = (trueSec) => { let trueSecClass = ''; trueSec = parseFloat(trueSec); @@ -1926,8 +1951,7 @@ define([ * @param option * @returns {string} */ - let getStatusInfoForSystem = function(status, option){ - + let getStatusInfoForSystem = (status, option) => { let statusInfo = ''; if( Init.systemStatus.hasOwnProperty(status) ){ @@ -1970,10 +1994,8 @@ define([ * @param sigGroupId * @returns {{}} */ - let getAllSignatureNames = function(systemTypeId, areaId, sigGroupId){ - + let getAllSignatureNames = (systemTypeId, areaId, sigGroupId) => { let signatureNames = {}; - if( SignatureType[systemTypeId] && SignatureType[systemTypeId][areaId] && @@ -2198,7 +2220,7 @@ define([ * get the current log data for the current user character * @returns {boolean} */ - let getCurrentCharacterLog = function(){ + let getCurrentCharacterLog = () => { let characterLog = false; let currentUserData = getCurrentUserData(); @@ -2382,7 +2404,7 @@ define([ * @param systemData * @param type */ - let setDestination = function(systemData, type){ + let setDestination = (systemData, type) => { let description = ''; switch(type){ case 'set_destination': @@ -2551,7 +2573,7 @@ define([ * -> system data where current user is located * @returns {{id: *, name: *}} */ - let getCurrentLocationData = function(){ + let getCurrentLocationData = () => { let currentLocationLink = $('#' + config.headCurrentLocationId).find('a'); return { id: currentLocationLink.data('systemId'), @@ -2563,7 +2585,7 @@ define([ * get all "open" dialog elements * @returns {*|jQuery} */ - let getOpenDialogs = function(){ + let getOpenDialogs = () => { return $('.' + config.dialogClass).filter(':visible'); }; diff --git a/public/js/v1.4.1/app/mappage.js b/public/js/v1.4.1/app/mappage.js index 2d5be008..f006d451 100644 --- a/public/js/v1.4.1/app/mappage.js +++ b/public/js/v1.4.1/app/mappage.js @@ -39,7 +39,6 @@ define([ Util.initDefaultEditableConfig(); // load page - // load info (maintenance) info panel (if scheduled) $('body').loadPageStructure().setGlobalShortcuts(); // show app information in browser console @@ -203,11 +202,6 @@ define([ // init map module mapModule.initMapModule(); - // load info (maintenance) info panel (if scheduled) - if(Init.programMode.maintenance){ - $('body').showGlobalInfoPanel(); - } - resolve({ action: 'initMapModule', data: false diff --git a/public/js/v1.4.1/app/page.js b/public/js/v1.4.1/app/page.js index 89c2cffb..f7e91be7 100644 --- a/public/js/v1.4.1/app/page.js +++ b/public/js/v1.4.1/app/page.js @@ -58,9 +58,7 @@ define([ headProgramStatusClass: 'pf-head-program-status', // class for "program status" notification // footer - pageFooterId: 'pf-footer', // id for page footer footerLicenceLinkClass: 'pf-footer-licence', // class for "licence" link - globalInfoPanelId: 'pf-global-info', // id for "global info panel" // menu menuHeadMenuLogoClass: 'pf-head-menu-logo', // class for main menu logo @@ -582,7 +580,7 @@ define([ let pageElement = $(this); let moduleData = { - id: config.pageFooterId, + id: Util.config.footerId, footerLicenceLinkClass: config.footerLicenceLinkClass, currentYear: new Date().getFullYear() }; @@ -1263,25 +1261,6 @@ define([ } }; - /** - * show information panel to active users (on bottom) - * @returns {*|jQuery|HTMLElement} - */ - $.fn.showGlobalInfoPanel = function(){ - let body = $(this); - let infoTemplate = 'text!templates/ui/info_panel.html'; - - requirejs([infoTemplate, 'mustache'], function(template, Mustache){ - let data = { - id: config.globalInfoPanelId - }; - let content = $( Mustache.render(template, data) ); - content.insertBefore('#' + config.pageFooterId ); - }); - - return body; - }; - /** * get all form Values as object * this includes all xEditable fields @@ -1331,5 +1310,4 @@ define([ initMapContextMenus: initMapContextMenus }; - }); \ No newline at end of file diff --git a/public/js/v1.4.1/app/util.js b/public/js/v1.4.1/app/util.js index 674f2e90..47e005be 100644 --- a/public/js/v1.4.1/app/util.js +++ b/public/js/v1.4.1/app/util.js @@ -43,6 +43,10 @@ define([ menuButtonCompactId: 'pf-menu-button-compact', // id for menu button "compact" UI map view menuButtonMapDeleteId: 'pf-menu-button-map-delete', // id for menu button "delete map" + // footer + footerId: 'pf-footer', // id for page footer + globalInfoPanelId: 'pf-global-info', // id for "global info panel" + settingsMessageVelocityOptions: { duration: 180 }, @@ -212,33 +216,6 @@ define([ }); }; - /** - * request a captcha image - * @param reason - * @param callback - */ - let getCaptchaImage = function(reason, callback){ - - $.ajax({ - type: 'POST', - url: Init.path.getCaptcha, - data: { - reason: reason - }, - dataType: 'json' - }).done(function(responseData){ - if(responseData.error.length > 0){ - showNotify({title: 'getCaptchaImage', text: 'Captcha image gneration failed', type: 'error'}); - }else{ - callback(responseData.img); - } - }).fail(function(jqXHR, status, error){ - let reason = status + ' ' + error; - showNotify({title: jqXHR.status + ': getCaptchaImage', text: reason, type: 'error'}); - }); - - }; - /** * reset/clear form fields * @returns {*} @@ -855,6 +832,26 @@ define([ }); }; + /** + * get all mapTabElements ( tags) + * or search for a specific tabElement within mapModule + * @param mapId + * @returns {JQuery|*|{}|T} + */ + $.fn.getMapTabElements = function(mapId){ + let mapModule = $(this); + let mapTabElements = mapModule.find('#' + config.mapTabBarId).find('a'); + + if(mapId){ + // search for a specific tab element + mapTabElements = mapTabElements.filter(function(i, el){ + return ( $(el).data('mapId') === mapId ); + }); + } + + return mapTabElements; + }; + /* * =============================================================================================================== * Util functions that are global available for all modules @@ -865,14 +862,14 @@ define([ * get current Pathfinder version number * @returns {*|jQuery} */ - let getVersion = function(){ + let getVersion = () => { return $('body').data('version'); }; /** * show current program version information in browser console */ - let showVersionInfo = function(){ + let showVersionInfo = () => { console.info('PATHFINDER ' + getVersion()); }; @@ -1140,6 +1137,31 @@ define([ '
'; }; + /** + * request a captcha image + * @param reason + * @param callback + */ + let getCaptchaImage = (reason, callback) => { + $.ajax({ + type: 'POST', + url: Init.path.getCaptcha, + data: { + reason: reason + }, + dataType: 'json' + }).done(function(responseData){ + if(responseData.error.length > 0){ + showNotify({title: 'getCaptchaImage', text: 'Captcha image generation failed', type: 'error'}); + }else{ + callback(responseData.img); + } + }).fail(function(jqXHR, status, error){ + let reason = status + ' ' + error; + showNotify({title: jqXHR.status + ': getCaptchaImage', text: reason, type: 'error'}); + }); + }; + /** * get the current main trigger delay for the main trigger functions * optional in/decrease the delay @@ -1237,7 +1259,6 @@ define([ * @param timerName */ let timeStart = timerName => { - if(typeof performance === 'object'){ stopTimerCache[timerName] = performance.now(); }else{ @@ -1251,7 +1272,6 @@ define([ * @returns {number} */ let timeStop = timerName => { - let duration = 0; if( stopTimerCache.hasOwnProperty(timerName) ){ @@ -1324,8 +1344,8 @@ define([ /** * stop browser tab title "blinking" */ - let stopTabBlink = function(){ - requirejs(['notification'], function(Notification){ + let stopTabBlink = () => { + requirejs(['notification'], Notification => { Notification.stopTabBlink(); }); }; @@ -1408,6 +1428,26 @@ define([ return tabId; }; + /** + * show information panel to active users (on bottom) + * @param show + */ + let toggleGlobalInfoPanel = (show = true) => { + let infoPanel = $('#' + config.globalInfoPanelId); + if( show && !infoPanel.length){ + // info panel not already shown + requirejs(['text!templates/ui/info_panel.html', 'mustache'], (template, Mustache) => { + let data = { + id: config.globalInfoPanelId + }; + let content = $(Mustache.render(template, data)); + content.insertBefore('#' + config.footerId); + }); + }else if (!show && infoPanel.length){ + infoPanel.remove(); + } + }; + /** * set default jQuery AJAX configuration */ @@ -1422,8 +1462,13 @@ define([ if(settings.crossDomain === false){ // add current character data to ANY XHR request (HTTP HEADER) // -> This helps to identify multiple characters on multiple browser tabs - jqXHR.setRequestHeader('Pf-Character', getCurrentCharacterId()); + jqXHR.setRequestHeader('pf-character', getCurrentCharacterId()); } + }, + complete: function(jqXHR, textStatus){ + // show "maintenance information panel -> if scheduled + let isMaintenance = parseInt(jqXHR.getResponseHeader('pf-maintenance')) || 0; + toggleGlobalInfoPanel(isMaintenance); } }); }; @@ -1559,26 +1604,6 @@ define([ }); }; - /** - * get all mapTabElements (
tags) - * or search for a specific tabElement within mapModule - * @param mapId - * @returns {JQuery|*|{}|T} - */ - $.fn.getMapTabElements = function(mapId){ - let mapModule = $(this); - let mapTabElements = mapModule.find('#' + config.mapTabBarId).find('a'); - - if(mapId){ - // search for a specific tab element - mapTabElements = mapTabElements.filter(function(i, el){ - return ( $(el).data('mapId') === mapId ); - }); - } - - return mapTabElements; - }; - /** * get mapElement from overlay or any child of that * @param mapOverlay @@ -1896,7 +1921,7 @@ define([ * @param trueSec * @returns {string} */ - let getTrueSecClassForSystem = function(trueSec){ + let getTrueSecClassForSystem = (trueSec) => { let trueSecClass = ''; trueSec = parseFloat(trueSec); @@ -1926,8 +1951,7 @@ define([ * @param option * @returns {string} */ - let getStatusInfoForSystem = function(status, option){ - + let getStatusInfoForSystem = (status, option) => { let statusInfo = ''; if( Init.systemStatus.hasOwnProperty(status) ){ @@ -1970,10 +1994,8 @@ define([ * @param sigGroupId * @returns {{}} */ - let getAllSignatureNames = function(systemTypeId, areaId, sigGroupId){ - + let getAllSignatureNames = (systemTypeId, areaId, sigGroupId) => { let signatureNames = {}; - if( SignatureType[systemTypeId] && SignatureType[systemTypeId][areaId] && @@ -2198,7 +2220,7 @@ define([ * get the current log data for the current user character * @returns {boolean} */ - let getCurrentCharacterLog = function(){ + let getCurrentCharacterLog = () => { let characterLog = false; let currentUserData = getCurrentUserData(); @@ -2382,7 +2404,7 @@ define([ * @param systemData * @param type */ - let setDestination = function(systemData, type){ + let setDestination = (systemData, type) => { let description = ''; switch(type){ case 'set_destination': @@ -2551,7 +2573,7 @@ define([ * -> system data where current user is located * @returns {{id: *, name: *}} */ - let getCurrentLocationData = function(){ + let getCurrentLocationData = () => { let currentLocationLink = $('#' + config.headCurrentLocationId).find('a'); return { id: currentLocationLink.data('systemId'), @@ -2563,7 +2585,7 @@ define([ * get all "open" dialog elements * @returns {*|jQuery} */ - let getOpenDialogs = function(){ + let getOpenDialogs = () => { return $('.' + config.dialogClass).filter(':visible'); }; diff --git a/public/templates/ui/info_panel.html b/public/templates/ui/info_panel.html index 5a94f13d..0d0d25cf 100644 --- a/public/templates/ui/info_panel.html +++ b/public/templates/ui/info_panel.html @@ -1,4 +1,4 @@
-

Scheduled maintenance: Pathfinder upgrade. v1.3.6 v1.4.0; Shutdown: ~13:00 (UTC). ETA ~14:00 (UTC)

+

Scheduled maintenance: Update v1.4.0 v1.4.1; Shutdown: ~11:00 (UTC). ETA ~11:15 (UTC)