From c21e33d2314c341e71f999617ff7329c524fb99f Mon Sep 17 00:00:00 2001 From: Mark Friedrich Date: Sat, 30 Mar 2019 08:57:38 +0100 Subject: [PATCH] - new confirmation dialog if users try to lazy update structures from Clipboard where current system != system marked for update (structure and signatures update now have the same logic) - improved WebSocket initialisation --- app/main/controller/admin.php | 2 +- app/main/controller/api/map.php | 2 +- app/main/lib/config.php | 13 ++-- app/main/lib/socket/AbstractSocket.php | 17 +++++- app/main/lib/socket/NullSocket.php | 38 ++++++++++++ app/main/lib/socket/SocketInterface.php | 13 ++-- app/main/lib/socket/TcpSocket.php | 6 ++ app/main/model/mapmodel.php | 2 +- js/app/logging.js | 2 +- js/app/ui/module/system_intel.js | 59 +++++++++++++++---- js/app/ui/module/system_signature.js | 3 +- public/js/v1.5.1/app/logging.js | 2 +- .../js/v1.5.1/app/ui/module/system_intel.js | 59 +++++++++++++++---- .../v1.5.1/app/ui/module/system_signature.js | 3 +- 14 files changed, 176 insertions(+), 45 deletions(-) create mode 100644 app/main/lib/socket/NullSocket.php diff --git a/app/main/controller/admin.php b/app/main/controller/admin.php index eb5a5a91..3a914f69 100644 --- a/app/main/controller/admin.php +++ b/app/main/controller/admin.php @@ -348,7 +348,7 @@ class Admin extends Controller{ * @param string $type * @return \Log */ - static function getLogger($type = 'ADMIN'){ + static function getLogger($type = 'ADMIN') : \Log { return parent::getLogger('ADMIN'); } diff --git a/app/main/controller/api/map.php b/app/main/controller/api/map.php index 563c33c2..5569d23c 100644 --- a/app/main/controller/api/map.php +++ b/app/main/controller/api/map.php @@ -54,7 +54,7 @@ class Map extends Controller\AccessController { // expire time in seconds $expireTimeCache = 60 * 60; - if( !$f3->exists(self::CACHE_KEY_INIT, $return )){ + if(!$f3->exists(self::CACHE_KEY_INIT, $return)){ // response should not be cached if invalid -> e.g. missing static data $validInitData = true; diff --git a/app/main/lib/config.php b/app/main/lib/config.php index 9fe41cd6..7a10c552 100644 --- a/app/main/lib/config.php +++ b/app/main/lib/config.php @@ -12,6 +12,7 @@ namespace lib; use lib\api\CcpClient; use lib\api\GitHubClient; use lib\api\SsoClient; +use lib\socket\AbstractSocket; use lib\socket\SocketInterface; use lib\socket\TcpSocket; @@ -109,7 +110,7 @@ class Config extends \Prefab { // Socket connectors $f3->set(TcpSocket::SOCKET_NAME, function(array $options = ['timeout' => 1]) : SocketInterface { - return new TcpSocket(self::getSocketUri(), $options); + return AbstractSocket::factory(TcpSocket::class, self::getSocketUri(), $options); }); } @@ -355,7 +356,7 @@ class Config extends \Prefab { * -> see pingDomain() * @return bool */ - static function validSocketConnect(): bool{ + static function validSocketConnect(string $uri) : bool{ $valid = false; $f3 = \Base::instance(); @@ -391,17 +392,17 @@ class Config extends \Prefab { * @param int $timeout * @return int */ - static function pingDomain(string $domain, int $port, $timeout = 1): int { - $starttime = microtime(true); + static function pingDomain(string $domain, int $port, $timeout = 1) : int { + $startTime = microtime(true); $file = @fsockopen ($domain, $port, $errno, $errstr, $timeout); - $stoptime = microtime(true); + $stopTime = microtime(true); if (!$file){ // Site is down $status = -1; }else { fclose($file); - $status = ($stoptime - $starttime) * 1000; + $status = ($stopTime - $startTime) * 1000; $status = floor($status); } return $status; diff --git a/app/main/lib/socket/AbstractSocket.php b/app/main/lib/socket/AbstractSocket.php index d7053a8a..f39c9804 100644 --- a/app/main/lib/socket/AbstractSocket.php +++ b/app/main/lib/socket/AbstractSocket.php @@ -52,7 +52,7 @@ abstract class AbstractSocket implements SocketInterface { /** * @return EventLoop\LoopInterface */ - public function getLoop(): EventLoop\LoopInterface { + protected function getLoop(): EventLoop\LoopInterface { if(!($this->loop instanceof EventLoop\LoopInterface)){ $this->loop = EventLoop\Factory::create(); } @@ -239,4 +239,19 @@ abstract class AbstractSocket implements SocketInterface { return $payload; } + /** + * use this function to create new Socket instances + * @param string $class + * @param string $uri + * @param array $options + * @return SocketInterface + */ + public static function factory(string $class, string $uri, array $options = []) : SocketInterface { + if(class_exists($class) && $uri){ + return new $class($uri, $options); + }else{ + // invalid Socket requirements -> return NullSocket + return new NullSocket($uri); + } + } } \ No newline at end of file diff --git a/app/main/lib/socket/NullSocket.php b/app/main/lib/socket/NullSocket.php new file mode 100644 index 00000000..9b60e3cb --- /dev/null +++ b/app/main/lib/socket/NullSocket.php @@ -0,0 +1,38 @@ +getLoop(), $this->options); + } + + /** + * write to NullSocket can not be performed + * @param string $task + * @param null $load + * @return Promise\PromiseInterface + */ + public function write(string $task, $load = null) : Promise\PromiseInterface { + return new Promise\RejectedPromise(); + } +} \ No newline at end of file diff --git a/app/main/lib/socket/SocketInterface.php b/app/main/lib/socket/SocketInterface.php index 57d9e386..e56bf33d 100644 --- a/app/main/lib/socket/SocketInterface.php +++ b/app/main/lib/socket/SocketInterface.php @@ -14,15 +14,18 @@ use React\Promise; interface SocketInterface { - /** - * @return EventLoop\LoopInterface - */ - public function getLoop(): EventLoop\LoopInterface; - /** * @param string $action * @param null $data * @return Promise\PromiseInterface */ public function write(string $action, $data = null) : Promise\PromiseInterface; + + /** + * @param string $class + * @param string $uri + * @param array $options + * @return SocketInterface + */ + public static function factory(string $class, string $uri, array $options = []) : SocketInterface; } \ No newline at end of file diff --git a/app/main/lib/socket/TcpSocket.php b/app/main/lib/socket/TcpSocket.php index e3355cf7..68dbb875 100644 --- a/app/main/lib/socket/TcpSocket.php +++ b/app/main/lib/socket/TcpSocket.php @@ -13,8 +13,14 @@ use React\Socket; class TcpSocket extends AbstractSocket { + /** + * name of Socket + */ const SOCKET_NAME = 'webSocket'; + /** + * @return Socket\ConnectorInterface + */ protected function getConnector(): Socket\ConnectorInterface { return new Socket\Connector($this->getLoop(), $this->options); } diff --git a/app/main/model/mapmodel.php b/app/main/model/mapmodel.php index b81f1d7b..36654ad9 100644 --- a/app/main/model/mapmodel.php +++ b/app/main/model/mapmodel.php @@ -985,7 +985,7 @@ class MapModel extends AbstractMapTrackingModel { // update map history *.log files ----------------------------------------------------------------------------- if($this->isHistoryLogEnabled()){ // check socket config - if(Config::validSocketConnect()){ + if(Config::validSocketConnect(Config::getSocketUri())){ $log->addHandler('socket', 'json', $this->getSocketConfig()); }else{ // update log file local (slow) diff --git a/js/app/logging.js b/js/app/logging.js index 3eb00ab6..aee42183 100644 --- a/js/app/logging.js +++ b/js/app/logging.js @@ -100,7 +100,7 @@ define([ // init log table logDataTable = logTable.DataTable({ - dom: '<"row"<"col-xs-3"l><"col-xs-5"B><"col-xs-4"f>>' + + dom: '<"row"<"col-xs-3"l><"col-xs-5"B><"col-xs-4"fS>>' + '<"row"<"col-xs-12"tr>>' + '<"row"<"col-xs-5"i><"col-xs-7"p>>', buttons: { diff --git a/js/app/ui/module/system_intel.js b/js/app/ui/module/system_intel.js index 6ca17543..8ae99f7e 100644 --- a/js/app/ui/module/system_intel.js +++ b/js/app/ui/module/system_intel.js @@ -258,12 +258,16 @@ define([ formData.corporationId = Util.getObjVal(formData, 'corporationId') | 0; formData.systemId = systemId | 0; - let method = formData.id ? 'PATCH' : 'PUT'; + moduleElement.showLoadingAnimation(); - Util.request(method, 'structure', formData.id, formData, { - moduleElement: moduleElement, - tableApi: tableApi - }).then( + let method = formData.id ? 'PATCH' : 'PUT'; + Util.request(method, 'structure', formData.id, formData, + { + moduleElement: moduleElement, + tableApi: tableApi + }, + context => context.moduleElement.hideLoadingAnimation() + ).then( payload => callbackUpdateStructureRows(payload.context, {structures: payload.data}), Util.handleAjaxErrorResponse ); @@ -582,10 +586,14 @@ define([ // let deleteRowElement = $(cell).parents('tr'); // tableApi.rows(deleteRowElement).remove().draw(); - Util.request('DELETE', 'structure', rowData.id, {}, { - moduleElement: moduleElement, - tableApi: tableApi - }).then( + moduleElement.showLoadingAnimation(); + Util.request('DELETE', 'structure', rowData.id, {}, + { + moduleElement: moduleElement, + tableApi: tableApi + }, + context => context.moduleElement.hideLoadingAnimation() + ).then( payload => callbackDeleteStructures(payload.context, payload.data), Util.handleAjaxErrorResponse ); @@ -732,13 +740,40 @@ define([ * @param context */ let updateStructureTableByClipboard = (systemData, clipboard, context) => { - let structureData = parseDscanString(systemData, clipboard); - if(structureData.length){ - Util.request('POST', 'structure', [], structureData, context) + + let saveStructureData = (structureData, context) => { + context.moduleElement.showLoadingAnimation(); + + Util.request('POST', 'structure', [], structureData, context, context => context.moduleElement.hideLoadingAnimation()) .then( payload => callbackUpdateStructureRows(payload.context, {structures: payload.data}), Util.handleAjaxErrorResponse ); + }; + + let structureData = parseDscanString(systemData, clipboard); + if(structureData.length){ + // valid structure data parsed + + // check if structures will be added to a system where character is currently in + // if character is not in any system -> id === undefined -> no "confirmation required + let currentLocationData = Util.getCurrentLocationData(); + if( + currentLocationData.id && + currentLocationData.id !== systemData.id + ){ + let systemNameStr = (systemData.name === systemData.alias) ? '"' + systemData.name + '"' : '"' + systemData.alias + '" (' + systemData.name + ')'; + systemNameStr = '' + systemNameStr + ''; + + let msg = 'Update structures in ' + systemNameStr + ' ? This not your current location, "' + currentLocationData.name + '" !'; + bootbox.confirm(msg, result => { + if(result){ + saveStructureData(structureData, context); + } + }); + }else{ + saveStructureData(structureData, context); + } } }; diff --git a/js/app/ui/module/system_signature.js b/js/app/ui/module/system_signature.js index 6770ac79..d6846067 100644 --- a/js/app/ui/module/system_signature.js +++ b/js/app/ui/module/system_signature.js @@ -720,13 +720,12 @@ define([ // valid signature data parsed // check if signatures will be added to a system where character is currently in - // if user is not in any system -> id === undefined -> no "confirmation required + // if character is not in any system -> id === undefined -> no "confirmation required let currentLocationData = Util.getCurrentLocationData(); if( currentLocationData.id && currentLocationData.id !== systemData.id ){ - let systemNameStr = (systemData.name === systemData.alias) ? '"' + systemData.name + '"' : '"' + systemData.alias + '" (' + systemData.name + ')'; systemNameStr = '' + systemNameStr + ''; diff --git a/public/js/v1.5.1/app/logging.js b/public/js/v1.5.1/app/logging.js index 3eb00ab6..aee42183 100644 --- a/public/js/v1.5.1/app/logging.js +++ b/public/js/v1.5.1/app/logging.js @@ -100,7 +100,7 @@ define([ // init log table logDataTable = logTable.DataTable({ - dom: '<"row"<"col-xs-3"l><"col-xs-5"B><"col-xs-4"f>>' + + dom: '<"row"<"col-xs-3"l><"col-xs-5"B><"col-xs-4"fS>>' + '<"row"<"col-xs-12"tr>>' + '<"row"<"col-xs-5"i><"col-xs-7"p>>', buttons: { diff --git a/public/js/v1.5.1/app/ui/module/system_intel.js b/public/js/v1.5.1/app/ui/module/system_intel.js index 6ca17543..8ae99f7e 100644 --- a/public/js/v1.5.1/app/ui/module/system_intel.js +++ b/public/js/v1.5.1/app/ui/module/system_intel.js @@ -258,12 +258,16 @@ define([ formData.corporationId = Util.getObjVal(formData, 'corporationId') | 0; formData.systemId = systemId | 0; - let method = formData.id ? 'PATCH' : 'PUT'; + moduleElement.showLoadingAnimation(); - Util.request(method, 'structure', formData.id, formData, { - moduleElement: moduleElement, - tableApi: tableApi - }).then( + let method = formData.id ? 'PATCH' : 'PUT'; + Util.request(method, 'structure', formData.id, formData, + { + moduleElement: moduleElement, + tableApi: tableApi + }, + context => context.moduleElement.hideLoadingAnimation() + ).then( payload => callbackUpdateStructureRows(payload.context, {structures: payload.data}), Util.handleAjaxErrorResponse ); @@ -582,10 +586,14 @@ define([ // let deleteRowElement = $(cell).parents('tr'); // tableApi.rows(deleteRowElement).remove().draw(); - Util.request('DELETE', 'structure', rowData.id, {}, { - moduleElement: moduleElement, - tableApi: tableApi - }).then( + moduleElement.showLoadingAnimation(); + Util.request('DELETE', 'structure', rowData.id, {}, + { + moduleElement: moduleElement, + tableApi: tableApi + }, + context => context.moduleElement.hideLoadingAnimation() + ).then( payload => callbackDeleteStructures(payload.context, payload.data), Util.handleAjaxErrorResponse ); @@ -732,13 +740,40 @@ define([ * @param context */ let updateStructureTableByClipboard = (systemData, clipboard, context) => { - let structureData = parseDscanString(systemData, clipboard); - if(structureData.length){ - Util.request('POST', 'structure', [], structureData, context) + + let saveStructureData = (structureData, context) => { + context.moduleElement.showLoadingAnimation(); + + Util.request('POST', 'structure', [], structureData, context, context => context.moduleElement.hideLoadingAnimation()) .then( payload => callbackUpdateStructureRows(payload.context, {structures: payload.data}), Util.handleAjaxErrorResponse ); + }; + + let structureData = parseDscanString(systemData, clipboard); + if(structureData.length){ + // valid structure data parsed + + // check if structures will be added to a system where character is currently in + // if character is not in any system -> id === undefined -> no "confirmation required + let currentLocationData = Util.getCurrentLocationData(); + if( + currentLocationData.id && + currentLocationData.id !== systemData.id + ){ + let systemNameStr = (systemData.name === systemData.alias) ? '"' + systemData.name + '"' : '"' + systemData.alias + '" (' + systemData.name + ')'; + systemNameStr = '' + systemNameStr + ''; + + let msg = 'Update structures in ' + systemNameStr + ' ? This not your current location, "' + currentLocationData.name + '" !'; + bootbox.confirm(msg, result => { + if(result){ + saveStructureData(structureData, context); + } + }); + }else{ + saveStructureData(structureData, context); + } } }; diff --git a/public/js/v1.5.1/app/ui/module/system_signature.js b/public/js/v1.5.1/app/ui/module/system_signature.js index 6770ac79..d6846067 100644 --- a/public/js/v1.5.1/app/ui/module/system_signature.js +++ b/public/js/v1.5.1/app/ui/module/system_signature.js @@ -720,13 +720,12 @@ define([ // valid signature data parsed // check if signatures will be added to a system where character is currently in - // if user is not in any system -> id === undefined -> no "confirmation required + // if character is not in any system -> id === undefined -> no "confirmation required let currentLocationData = Util.getCurrentLocationData(); if( currentLocationData.id && currentLocationData.id !== systemData.id ){ - let systemNameStr = (systemData.name === systemData.alias) ? '"' + systemData.name + '"' : '"' + systemData.alias + '" (' + systemData.name + ')'; systemNameStr = '' + systemNameStr + '';