- new option enables "auto select system", closed #569
- improved `console` logging format
This commit is contained in:
@@ -183,6 +183,11 @@ class Map extends Controller\AccessController {
|
||||
'zKillboard' => Config::getPathfinderData('api.z_killboard')
|
||||
];
|
||||
|
||||
// Character default config -------------------------------------------------------------------------------
|
||||
$return->character = [
|
||||
'autoLocationSelect' => (bool)Config::getPathfinderData('character.auto_location_select')
|
||||
];
|
||||
|
||||
// Slack integration status -------------------------------------------------------------------------------
|
||||
$return->slack = [
|
||||
'status' => (bool)Config::getPathfinderData('slack.status')
|
||||
|
||||
@@ -329,7 +329,7 @@ class User extends Controller\Controller{
|
||||
|
||||
// character config -----------------------------------------------------------
|
||||
if(isset($formData['character'])){
|
||||
$activeCharacter->logLocation = (int)$formData['logLocation'];
|
||||
$activeCharacter->copyfrom($formData, ['logLocation', 'selectLocation']);
|
||||
|
||||
$activeCharacter->save();
|
||||
}
|
||||
|
||||
@@ -142,6 +142,11 @@ class CharacterModel extends BasicModel {
|
||||
'nullable' => false,
|
||||
'default' => 1
|
||||
],
|
||||
'selectLocation' => [
|
||||
'type' => Schema::DT_BOOL,
|
||||
'nullable' => false,
|
||||
'default' => 0
|
||||
],
|
||||
'securityStatus' => [
|
||||
'type' => Schema::DT_FLOAT,
|
||||
'nullable' => false,
|
||||
@@ -186,6 +191,7 @@ class CharacterModel extends BasicModel {
|
||||
$characterData->role = $this->roleId->getData();
|
||||
$characterData->shared = $this->shared;
|
||||
$characterData->logLocation = $this->logLocation;
|
||||
$characterData->selectLocation = $this->selectLocation;
|
||||
|
||||
if($this->authStatus){
|
||||
$characterData->authStatus = $this->authStatus;
|
||||
|
||||
@@ -36,12 +36,15 @@ CHARACTER =
|
||||
CORPORATION =
|
||||
ALLIANCE =
|
||||
|
||||
[PATHFINDER.CHARACTER]
|
||||
AUTO_LOCATION_SELECT = 1
|
||||
|
||||
; Slack API integration ===========================================================================
|
||||
[PATHFINDER.SLACK]
|
||||
; Global Slack API status, check PATHFINDER.MAP section for individual control (0=disabled, 1=enabled)
|
||||
STATUS = 1
|
||||
|
||||
; Slack API integration ===========================================================================
|
||||
; Discord API integration =========================================================================
|
||||
[PATHFINDER.DISCORD]
|
||||
; Global Discord API status, check PATHFINDER.MAP section for individual control (0=disabled, 1=enabled)
|
||||
STATUS = 1
|
||||
|
||||
215
js/app/console.js
Normal file
215
js/app/console.js
Normal file
@@ -0,0 +1,215 @@
|
||||
/**
|
||||
* Console module
|
||||
* -> extends default window.console log object
|
||||
*/
|
||||
|
||||
define([], () => {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* init custom window.console object
|
||||
* -> extend console obj with custom methods for styling and logging
|
||||
*/
|
||||
let initConsole = () => {
|
||||
|
||||
window.console = (origConsole => {
|
||||
// save orig methods for byPassing args to original methods
|
||||
let log = origConsole.log;
|
||||
let info = origConsole.info;
|
||||
let warn = origConsole.warn;
|
||||
let error = origConsole.error;
|
||||
|
||||
let styles = {
|
||||
'indentDefault': {
|
||||
'padding-left': '3px'
|
||||
},
|
||||
'global': {
|
||||
'font-weight': 500,
|
||||
'font-size': '11px',
|
||||
'line-height': '19px',
|
||||
'font-family': '"Fira Code", "Lucida Console"',
|
||||
},
|
||||
'ok': {
|
||||
'color': '#5cb85c'
|
||||
},
|
||||
'log': {
|
||||
'color': '#adadad'
|
||||
},
|
||||
'info': {
|
||||
'color': '#428bca'
|
||||
},
|
||||
'warn': {
|
||||
'color': '#ffdd9e'
|
||||
},
|
||||
'error': {
|
||||
'color': '#ff8080'
|
||||
},
|
||||
'pf': {
|
||||
'color': '#568a89'
|
||||
},
|
||||
'brand': {
|
||||
'color': '#375959',
|
||||
'line-height': '35px',
|
||||
'font-size': '25px'
|
||||
}
|
||||
};
|
||||
|
||||
let placeholders = {
|
||||
'%s': {
|
||||
'style': ['color: #e93f3b; font-style: italic', 'color: inherit']
|
||||
},
|
||||
'%i': {
|
||||
'style': ['color: #9980ff', 'color: inherit'],
|
||||
},
|
||||
'%d': {
|
||||
'style': ['color: #9980ff', 'color: inherit']
|
||||
},
|
||||
'%f': {
|
||||
'style': ['color: #9980ff', 'color: inherit']
|
||||
},
|
||||
'%o': {
|
||||
'style': ['', '']
|
||||
},
|
||||
'%O': {
|
||||
'style': ['', '']
|
||||
}
|
||||
};
|
||||
|
||||
let findPlaceholders = str => {
|
||||
let exp = new RegExp(Object.keys(placeholders).join('|'), 'g');
|
||||
let matches = str.match(exp);
|
||||
return matches ? matches : [];
|
||||
};
|
||||
|
||||
let addStylePlaceholder = str => {
|
||||
let exp = new RegExp(Object.keys(placeholders).join('|'), 'g');
|
||||
|
||||
return str.replace(exp, function(matched){
|
||||
return '%c' + matched + '%c';
|
||||
});
|
||||
};
|
||||
|
||||
let getStyleByPlaceholder = (placeholder, clear = false) => {
|
||||
let css = '';
|
||||
if(placeholders.hasOwnProperty(placeholder)){
|
||||
css = placeholders[placeholder].style[clear ? 1 : 0];
|
||||
}
|
||||
return css;
|
||||
};
|
||||
|
||||
let getStyleByLogType = (logType, props = []) => {
|
||||
let css = '';
|
||||
if(styles.hasOwnProperty(logType)){
|
||||
css = Object.keys(styles[logType])
|
||||
.filter(prop => props.length ? props.includes(prop) : true)
|
||||
.reduce((css, prop,i, affe) => {
|
||||
css += prop + ':' + styles[logType][prop] + ';';
|
||||
return css;
|
||||
}, '');
|
||||
}
|
||||
return css;
|
||||
};
|
||||
|
||||
let setLineStyleByLogType = (logType, args) => {
|
||||
if(args.length){
|
||||
let lineStyle = getStyleByLogType('global') + getStyleByLogType(logType);
|
||||
lineStyle += ['ok', 'log', 'info', 'pf'].includes(logType) ? getStyleByLogType('indentDefault') : '';
|
||||
let bullet = ['ok', 'log', 'info', 'pf'].includes(logType) ? '●' : '';
|
||||
|
||||
if(typeof args[0] === 'string'){
|
||||
// prepend placeholder to existing message
|
||||
args[0] = '%c' + bullet + ' ' + args[0];
|
||||
}else{
|
||||
// prepend placeholder as new message
|
||||
args.splice(0, 0, '%c' + bullet + ' ' + logType + ':');
|
||||
}
|
||||
// set line style as 2nd argument
|
||||
args.splice(1, 0, lineStyle);
|
||||
}
|
||||
};
|
||||
|
||||
let setMessageStyleByLogType = (logType, args) => {
|
||||
if(typeof args[0] === 'string') {
|
||||
let placeholdersFound = findPlaceholders(args[0]);
|
||||
let placeholderCount = placeholdersFound.length;
|
||||
|
||||
// add c% placeholders around other placeholders
|
||||
args[0] = addStylePlaceholder(args[0]);
|
||||
|
||||
// add style args for c% placeholders
|
||||
let placeholderIndex = 0;
|
||||
let argIndexStart = 1;
|
||||
let argIndexEnd = argIndexStart + placeholderCount;
|
||||
let argIndexOffset = 0;
|
||||
for (let argIndex = argIndexStart; argIndex < argIndexEnd; argIndex++) {
|
||||
args.splice(argIndex + argIndexOffset, 0, getStyleByPlaceholder(placeholdersFound[placeholderIndex]));
|
||||
argIndexOffset += 2;
|
||||
args.splice(argIndex + argIndexOffset, 0, getStyleByPlaceholder(placeholdersFound[placeholderIndex], true) + ';' + getStyleByLogType('global') + getStyleByLogType(logType));
|
||||
placeholderIndex++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
origConsole.ok = (...args) => {
|
||||
setMessageStyleByLogType('ok', args);
|
||||
setLineStyleByLogType('ok', args);
|
||||
info.apply(origConsole, args);
|
||||
};
|
||||
|
||||
origConsole.info = (...args) => {
|
||||
setMessageStyleByLogType('info', args);
|
||||
setLineStyleByLogType('info', args);
|
||||
info.apply(origConsole, args);
|
||||
};
|
||||
|
||||
origConsole.log = (...args) => {
|
||||
setMessageStyleByLogType('log', args);
|
||||
setLineStyleByLogType('log', args);
|
||||
log.apply(origConsole, args);
|
||||
};
|
||||
|
||||
origConsole.warn = (...args) => {
|
||||
setMessageStyleByLogType('warn', args);
|
||||
setLineStyleByLogType('warn', args);
|
||||
warn.apply(origConsole, args);
|
||||
};
|
||||
|
||||
origConsole.error = (...args) => {
|
||||
setMessageStyleByLogType('error', args);
|
||||
setLineStyleByLogType('error', args);
|
||||
error.apply(origConsole, args);
|
||||
};
|
||||
|
||||
origConsole.pf = (...args) => {
|
||||
setMessageStyleByLogType('pf', args);
|
||||
setLineStyleByLogType('pf', args);
|
||||
info.apply(origConsole, args);
|
||||
};
|
||||
|
||||
origConsole.brand = (...args) => {
|
||||
setMessageStyleByLogType('brand', args);
|
||||
setLineStyleByLogType('brand', args);
|
||||
info.apply(origConsole, args);
|
||||
};
|
||||
|
||||
return origConsole;
|
||||
})(window.console);
|
||||
};
|
||||
|
||||
initConsole();
|
||||
|
||||
/**
|
||||
* show current program version information console
|
||||
* @param version
|
||||
*/
|
||||
let showVersionInfo = (version) => {
|
||||
console.ok('%c PATHFINDER',
|
||||
'color: #477372; font-size: 25px; margin-left: 10px; line-height: 100px; text-shadow: 1px 1px 0 #212C30; ' +
|
||||
'background: url(https://i.imgur.com/1Gw8mjL.png) no-repeat;');
|
||||
console.pf('Release: %s', version);
|
||||
};
|
||||
|
||||
return {
|
||||
showVersionInfo: showVersionInfo
|
||||
};
|
||||
});
|
||||
@@ -1495,7 +1495,7 @@ define([
|
||||
hiddenOptions.push('delete_system');
|
||||
}
|
||||
|
||||
let mapElement = component.parents('.' + config.mapClass);
|
||||
let mapElement = component.closest('.' + config.mapClass);
|
||||
if( !mapElement.find('.' + config.systemActiveClass).length ){
|
||||
hiddenOptions.push('find_route');
|
||||
}
|
||||
@@ -1827,7 +1827,7 @@ define([
|
||||
let single = function(e){
|
||||
// check if click was performed on "popover" (x-editable)
|
||||
let popoverClick = false;
|
||||
if( $(e.target).parents('.popover').length ){
|
||||
if( $(e.target).closest('.popover').length ){
|
||||
popoverClick = true;
|
||||
}
|
||||
|
||||
@@ -2014,7 +2014,7 @@ define([
|
||||
// register all available connection types ----------------------------------------------------------------
|
||||
newJsPlumbInstance.registerConnectionTypes(globalMapConfig.connectionTypes);
|
||||
|
||||
// event after a new connection is established --------------------------
|
||||
// event after a new connection is established ------------------------------------------------------------
|
||||
newJsPlumbInstance.bind('connection', function(info, e){
|
||||
// set connection observer
|
||||
setConnectionObserver(newJsPlumbInstance, info.connection);
|
||||
@@ -2114,6 +2114,54 @@ define([
|
||||
return MapUtil.getMapInstance(mapId);
|
||||
};
|
||||
|
||||
/**
|
||||
* check if there is an focus() element found as parent of tabContentElement
|
||||
* -> or if there is any other active UI element found (e.g. dialog, xEditable, Summernote)
|
||||
* @param tabContentElement
|
||||
* @returns {*}
|
||||
*/
|
||||
let systemFormsActive = (tabContentElement) => {
|
||||
let activeNode = null;
|
||||
if(tabContentElement.length){
|
||||
// tabContentElement exists ...
|
||||
tabContentElement = tabContentElement[0];
|
||||
|
||||
// ... check for current active/focus() element and is not the default <body> element ...
|
||||
if(
|
||||
Util.isDomElement(document.activeElement) &&
|
||||
document.activeElement !== document.body
|
||||
){
|
||||
let activeElementTagName = document.activeElement.tagName.toLocaleLowerCase();
|
||||
|
||||
// ... check for active form elements ...
|
||||
let isFormElement = ['input', 'select', 'textarea'].includes(activeElementTagName);
|
||||
let isChildElement = tabContentElement.contains(document.activeElement);
|
||||
|
||||
if(isFormElement && isChildElement){
|
||||
activeNode = activeElementTagName;
|
||||
}else{
|
||||
// ... check for open dialogs/xEditable elements ...
|
||||
if(Util.isDomElement(document.querySelector('.bootbox'))){
|
||||
activeNode = 'dialogOpen';
|
||||
}else if(Util.isDomElement(document.querySelector('.editable-open'))){
|
||||
activeNode = 'xEditableOpen';
|
||||
}else{
|
||||
// ... check for open Summernote editor
|
||||
let summernoteElement = tabContentElement.querySelector('.' + Util.config.summernoteClass);
|
||||
if(
|
||||
Util.isDomElement(summernoteElement) &&
|
||||
typeof $(summernoteElement).data().summernote === 'object'
|
||||
){
|
||||
activeNode = 'SummernoteOpen';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return activeNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* set observer for a map container
|
||||
* @param map
|
||||
@@ -2484,17 +2532,30 @@ define([
|
||||
|
||||
// triggered from "header" link (if user is active in one of the systems)
|
||||
mapContainer.on('pf:menuSelectSystem', function(e, data){
|
||||
let tempMapContainer = $(this);
|
||||
let systemId = MapUtil.getSystemId(tempMapContainer.data('id'), data.systemId);
|
||||
let system = $(this).find('#' + systemId);
|
||||
let mapElement = $(this);
|
||||
let systemId = MapUtil.getSystemId(mapElement.data('id'), data.systemId);
|
||||
let system = mapElement.find('#' + systemId);
|
||||
|
||||
if(system.length === 1){
|
||||
// scroll to system
|
||||
let tempMapWrapper = tempMapContainer.parents('.' + config.mapWrapperClass);
|
||||
tempMapWrapper.mCustomScrollbar('scrollTo', system);
|
||||
// system found on map ...
|
||||
let select = Util.getObjVal(data, 'forceSelect') !== false;
|
||||
|
||||
// select system
|
||||
MapUtil.showSystemInfo(map, system);
|
||||
if(!select){
|
||||
// ... select is NOT "forced" -> auto select system on jump
|
||||
let activeElement = systemFormsActive(MapUtil.getTabContentElementByMapElement(system));
|
||||
if(activeElement !== null){
|
||||
console.info('Skip auto select systemId %i. Reason: %o', data.systemId, activeElement);
|
||||
}else{
|
||||
select = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(select){
|
||||
let mapWrapper = mapElement.closest('.' + config.mapWrapperClass);
|
||||
mapWrapper.scrollToSystem(MapUtil.getSystemPosition(system));
|
||||
// select system
|
||||
MapUtil.showSystemInfo(map, system);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2595,118 +2656,125 @@ define([
|
||||
/**
|
||||
* updates all systems on map with current user Data (all users on this map)
|
||||
* update the Data of the user that is currently viewing the map (if available)
|
||||
* @param mapElement
|
||||
* @param userData
|
||||
* @returns {boolean}
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
$.fn.updateUserData = function(userData){
|
||||
let returnStatus = true;
|
||||
let updateUserData = (mapElement, userData) => {
|
||||
|
||||
// get new map instance or load existing
|
||||
let map = getMapInstance(userData.config.id);
|
||||
|
||||
let mapElement = map.getContainer();
|
||||
|
||||
// container must exist! otherwise systems can not be updated
|
||||
if(mapElement !== undefined){
|
||||
mapElement = $(mapElement);
|
||||
|
||||
// check if map is frozen
|
||||
if(mapElement.data('frozen') === true){
|
||||
return returnStatus;
|
||||
}
|
||||
|
||||
// compact/small system layout or not
|
||||
let compactView = mapElement.hasClass(MapUtil.config.mapCompactClass);
|
||||
|
||||
// get current character log data
|
||||
let characterLogExists = false;
|
||||
let currentCharacterLog = Util.getCurrentCharacterLog();
|
||||
|
||||
// data for header update
|
||||
let headerUpdateData = {
|
||||
mapId: userData.config.id,
|
||||
userCountInside: 0, // active user on a map
|
||||
userCountOutside: 0, // active user NOT on map
|
||||
userCountInactive: 0 // inactive users (no location)
|
||||
let updateUserDataExecutor = (resolve, reject) => {
|
||||
let payload = {
|
||||
action: 'updateUserData'
|
||||
};
|
||||
|
||||
if(
|
||||
currentCharacterLog &&
|
||||
currentCharacterLog.system
|
||||
){
|
||||
characterLogExists = true;
|
||||
headerUpdateData.currentSystemName = currentCharacterLog.system.name;
|
||||
}
|
||||
// get new map instance or load existing
|
||||
let map = getMapInstance(userData.config.id);
|
||||
let mapElement = map.getContainer();
|
||||
|
||||
// check if current user was found on the map
|
||||
let currentUserOnMap = false;
|
||||
// container must exist! otherwise systems can not be updated
|
||||
if(mapElement !== undefined){
|
||||
mapElement = $(mapElement);
|
||||
|
||||
// get all systems
|
||||
let systems = mapElement.find('.' + config.systemClass);
|
||||
|
||||
for(let i = 0; i < systems.length; i++){
|
||||
// get user Data for System
|
||||
|
||||
let system = $( systems[i] );
|
||||
|
||||
let systemId = $(system).data('systemId');
|
||||
|
||||
let tempUserData = null;
|
||||
|
||||
// check if user is currently in "this" system
|
||||
let currentUserIsHere = false;
|
||||
|
||||
let j = userData.data.systems.length;
|
||||
|
||||
// search backwards to avoid decrement the counter after splice()
|
||||
while(j--){
|
||||
let systemData = userData.data.systems[j];
|
||||
|
||||
// check if any user is in this system
|
||||
if(systemId === systemData.id){
|
||||
tempUserData = systemData;
|
||||
|
||||
// add "user count" to "total map user count"
|
||||
headerUpdateData.userCountInside += tempUserData.user.length;
|
||||
|
||||
// remove system from "search" array -> speed up loop
|
||||
userData.data.systems.splice(j, 1);
|
||||
}
|
||||
// no user update for 'frozen' maps...
|
||||
if(mapElement.data('frozen') === true){
|
||||
return resolve(payload);
|
||||
}
|
||||
|
||||
// the current user can only be in a single system ----------------------------------------------------
|
||||
// compact/small system layout or not
|
||||
let compactView = mapElement.hasClass(MapUtil.config.mapCompactClass);
|
||||
|
||||
// get current character log data
|
||||
let characterLogExists = false;
|
||||
let currentCharacterLog = Util.getCurrentCharacterLog();
|
||||
|
||||
// data for header update
|
||||
let headerUpdateData = {
|
||||
mapId: userData.config.id,
|
||||
userCountInside: 0, // active user on a map
|
||||
userCountOutside: 0, // active user NOT on map
|
||||
userCountInactive: 0, // inactive users (no location)
|
||||
currentLocation: {
|
||||
id: 0, // systemId for current active user
|
||||
name: false // systemName for current active user
|
||||
}
|
||||
};
|
||||
|
||||
if(
|
||||
characterLogExists &&
|
||||
currentCharacterLog.system.id === systemId
|
||||
currentCharacterLog &&
|
||||
currentCharacterLog.system
|
||||
){
|
||||
if( !currentUserOnMap ){
|
||||
currentUserIsHere = true;
|
||||
currentUserOnMap = true;
|
||||
characterLogExists = true;
|
||||
headerUpdateData.currentLocation.name = currentCharacterLog.system.name;
|
||||
}
|
||||
|
||||
// set current location data for header update
|
||||
headerUpdateData.currentSystemId = $(system).data('id');
|
||||
headerUpdateData.currentSystemName = currentCharacterLog.system.name;
|
||||
// check if current user was found on the map
|
||||
let currentUserOnMap = false;
|
||||
|
||||
// get all systems
|
||||
let systems = mapElement.find('.' + config.systemClass);
|
||||
|
||||
for(let system of systems){
|
||||
system = $(system);
|
||||
let systemId = system.data('systemId');
|
||||
let tempUserData = null;
|
||||
|
||||
// check if user is currently in "this" system
|
||||
let currentUserIsHere = false;
|
||||
|
||||
let j = userData.data.systems.length;
|
||||
|
||||
// search backwards to avoid decrement the counter after splice()
|
||||
while(j--){
|
||||
let systemData = userData.data.systems[j];
|
||||
|
||||
// check if any user is in this system
|
||||
if(systemId === systemData.id){
|
||||
tempUserData = systemData;
|
||||
|
||||
// add "user count" to "total map user count"
|
||||
headerUpdateData.userCountInside += tempUserData.user.length;
|
||||
|
||||
// remove system from "search" array -> speed up loop
|
||||
userData.data.systems.splice(j, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// the current user can only be in a single system ------------------------------------------------
|
||||
if(
|
||||
characterLogExists &&
|
||||
currentCharacterLog.system.id === systemId
|
||||
){
|
||||
if( !currentUserOnMap ){
|
||||
currentUserIsHere = true;
|
||||
currentUserOnMap = true;
|
||||
|
||||
// set current location data for header update
|
||||
headerUpdateData.currentLocation.id = system.data('id');
|
||||
headerUpdateData.currentLocation.name = currentCharacterLog.system.name;
|
||||
}
|
||||
}
|
||||
|
||||
system.updateSystemUserData(map, tempUserData, currentUserIsHere, {compactView: compactView});
|
||||
}
|
||||
|
||||
// users who are not in any map system ----------------------------------------------------------------
|
||||
for(let systemData of userData.data.systems){
|
||||
// users without location are grouped in systemId: 0
|
||||
if(systemData.id){
|
||||
headerUpdateData.userCountOutside += systemData.user.length;
|
||||
}else{
|
||||
headerUpdateData.userCountInactive += systemData.user.length;
|
||||
}
|
||||
}
|
||||
|
||||
system.updateSystemUserData(map, tempUserData, currentUserIsHere, {compactView: compactView});
|
||||
// trigger document event -> update header
|
||||
$(document).trigger('pf:updateHeaderMapData', headerUpdateData);
|
||||
}
|
||||
|
||||
// users who are not in any map system --------------------------------------------------------------------
|
||||
for(let i = 0; i < userData.data.systems.length; i++){
|
||||
// users without location are grouped in systemId: 0
|
||||
if(userData.data.systems[i].id){
|
||||
headerUpdateData.userCountOutside += userData.data.systems[i].user.length;
|
||||
}else{
|
||||
headerUpdateData.userCountInactive += userData.data.systems[i].user.length;
|
||||
}
|
||||
}
|
||||
resolve(payload);
|
||||
};
|
||||
|
||||
// trigger document event -> update header
|
||||
$(document).trigger('pf:updateHeaderMapData', headerUpdateData);
|
||||
}
|
||||
|
||||
return returnStatus;
|
||||
return new Promise(updateUserDataExecutor);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2851,17 +2919,7 @@ define([
|
||||
updated: parseInt( system.data('updated') )
|
||||
};
|
||||
systemData.userCount = (system.data('userCount') ? parseInt( system.data('userCount') ) : 0);
|
||||
|
||||
// position ---------------------------------------------------------------------------------------------------
|
||||
let positionData = {};
|
||||
let currentX = system.css('left');
|
||||
let currentY = system.css('top');
|
||||
|
||||
// remove 'px'
|
||||
positionData.x = parseInt( currentX.substring(0, currentX.length - 2) );
|
||||
positionData.y = parseInt( currentY.substring(0, currentY.length - 2) );
|
||||
|
||||
systemData.position = positionData;
|
||||
systemData.position = MapUtil.getSystemPosition(system);
|
||||
|
||||
return systemData;
|
||||
};
|
||||
@@ -2982,6 +3040,7 @@ define([
|
||||
return {
|
||||
getMapInstance: getMapInstance,
|
||||
loadMap: loadMap,
|
||||
updateUserData: updateUserData,
|
||||
saveSystemCallback: saveSystemCallback
|
||||
};
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ define([
|
||||
};
|
||||
|
||||
/**
|
||||
* scroll to a specific position in the map
|
||||
* scroll to a specific position on map
|
||||
* demo: http://manos.malihu.gr/repository/custom-scrollbar/demo/examples/scrollTo_demo.html
|
||||
* @param position
|
||||
*/
|
||||
@@ -79,4 +79,31 @@ define([
|
||||
$(this).mCustomScrollbar('scrollTo', position);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* scroll to a specific system on map
|
||||
* -> subtract some offset for tooltips/connections
|
||||
* @param position
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.scrollToSystem = function(position){
|
||||
position = getOffsetPosition(position, {x: -15, y: -35});
|
||||
return this.each(function(){
|
||||
$(this).mCustomScrollbar('scrollTo', position);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* add/subtract offset coordinates from position
|
||||
* -> no negative values returned
|
||||
* @param position
|
||||
* @param offset
|
||||
* @returns {{x: number, y: number}}
|
||||
*/
|
||||
let getOffsetPosition = (position, offset) => {
|
||||
return {
|
||||
x: Math.max(0, position.x + offset.x),
|
||||
y: Math.max(0, position.y + offset.y)
|
||||
};
|
||||
};
|
||||
});
|
||||
@@ -482,7 +482,7 @@ define([
|
||||
* @param label
|
||||
* @returns {string}
|
||||
*/
|
||||
let getEndpointOverlayContent = (label) => {
|
||||
let getEndpointOverlayContent = label => {
|
||||
let newLabel = '';
|
||||
let colorClass = 'txt-color-grayLighter';
|
||||
|
||||
@@ -508,17 +508,14 @@ define([
|
||||
* @param element
|
||||
* @returns {*}
|
||||
*/
|
||||
let getTabContentElementByMapElement = (element) => {
|
||||
let tabContentElement = $(element).parents('.' + config.mapTabContentClass);
|
||||
return tabContentElement;
|
||||
};
|
||||
let getTabContentElementByMapElement = element => $(element).closest('.' + config.mapTabContentClass);
|
||||
|
||||
/**
|
||||
* checks if there is an "active" connection on a map
|
||||
* @param map
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let hasActiveConnection = (map) => {
|
||||
let hasActiveConnection = map => {
|
||||
let activeConnections = getConnectionsByType(map, 'active');
|
||||
return activeConnections.length > 0;
|
||||
};
|
||||
@@ -1203,6 +1200,21 @@ define([
|
||||
return new Promise(setMapDefaultOptionsExecutor);
|
||||
};
|
||||
|
||||
/**
|
||||
* get system coordinates from systemElement
|
||||
* @param system
|
||||
* @returns {{x: number, y: number}}
|
||||
*/
|
||||
let getSystemPosition = system => {
|
||||
let x = system.css('left');
|
||||
let y = system.css('top');
|
||||
|
||||
return {
|
||||
x: parseInt(x.substring(0, x.length - 2)),
|
||||
y: parseInt(y.substring(0, y.length - 2))
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* scroll map to default (stored) x/y coordinates
|
||||
* @param mapElement
|
||||
@@ -1755,6 +1767,7 @@ define([
|
||||
deleteLocalData: deleteLocalData,
|
||||
visualizeMap: visualizeMap,
|
||||
setMapDefaultOptions: setMapDefaultOptions,
|
||||
getSystemPosition: getSystemPosition,
|
||||
scrollToDefaultPosition: scrollToDefaultPosition,
|
||||
getSystemId: getSystemId,
|
||||
checkRight: checkRight,
|
||||
|
||||
@@ -143,6 +143,7 @@ define([
|
||||
Init.characterStatus = response.characterStatus;
|
||||
Init.routes = response.routes;
|
||||
Init.url = response.url;
|
||||
Init.character = response.character;
|
||||
Init.slack = response.slack;
|
||||
Init.discord = response.discord;
|
||||
Init.structureStatus = response.structureStatus;
|
||||
@@ -308,10 +309,10 @@ define([
|
||||
.then(payload => Promise.all([initMapModule(payload[0]), initMapWorker(payload[1])]))
|
||||
.then(payload => {
|
||||
// mapModule initialized and WebSocket configuration working
|
||||
console.info('%s() complete! command: "%s"; syncStatus: "%s"',
|
||||
payload[1].action,
|
||||
payload[1].data.command,
|
||||
payload[1].data.syncStatus
|
||||
console.ok('Client syncStatus: %s. %O resolved by command: %s!',
|
||||
payload[1].data.syncStatus,
|
||||
payload[1].action + '()',
|
||||
payload[1].data.command
|
||||
);
|
||||
})
|
||||
.catch(payload => {
|
||||
@@ -322,10 +323,10 @@ define([
|
||||
break;
|
||||
case 'initMapWorker':
|
||||
// WebSocket not working -> no error here -> fallback to Ajax
|
||||
console.warn('%s() rejects Promise. command: "%s"; syncStatus: "%s", payload: %o',
|
||||
payload.action,
|
||||
payload.data.command,
|
||||
console.info('Client syncStatus: %s. %O rejected by command: %s! payload: %o',
|
||||
payload.data.syncStatus,
|
||||
payload.action + '()',
|
||||
payload.data.command,
|
||||
payload.data
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -458,7 +458,7 @@ define([
|
||||
mapElement.trigger('pf:updateLocal', currentMapUserData);
|
||||
|
||||
// update map with current user data
|
||||
mapElement.updateUserData(currentMapUserData);
|
||||
Map.updateUserData(mapElement, currentMapUserData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -491,7 +491,7 @@ define([
|
||||
|
||||
pageElement.prepend(headRendered);
|
||||
|
||||
// init header =====================================================================
|
||||
// init header ================================================================================================
|
||||
|
||||
// init slide menus
|
||||
let slideMenu = new $.slidebars({
|
||||
@@ -516,7 +516,7 @@ define([
|
||||
|
||||
// current location
|
||||
$('#' + Util.config.headCurrentLocationId).find('a').on('click', function(){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: $(this).data('systemId') });
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: $(this).data('systemId')});
|
||||
});
|
||||
|
||||
// program status
|
||||
@@ -589,7 +589,7 @@ define([
|
||||
|
||||
pageElement.prepend(footerElement);
|
||||
|
||||
// init footer ==================================================
|
||||
// init footer ================================================================================================
|
||||
pageElement.find('.' + config.footerLicenceLinkClass).on('click', function(){
|
||||
//show credits info dialog
|
||||
$.fn.showCreditsDialog();
|
||||
@@ -728,7 +728,7 @@ define([
|
||||
return false;
|
||||
});
|
||||
|
||||
// END menu events =============================================================================
|
||||
// END menu events ============================================================================================
|
||||
|
||||
// global "popover" callback (for all popovers)
|
||||
$('.' + Util.config.popoverTriggerClass).on('hide.bs.popover', function(e){
|
||||
@@ -772,7 +772,7 @@ define([
|
||||
userCountInside = data.userCountInside;
|
||||
userCountOutside = data.userCountOutside;
|
||||
userCountInactive = data.userCountInactive;
|
||||
currentLocationData = data;
|
||||
currentLocationData = data.currentLocation;
|
||||
}
|
||||
updateHeaderActiveUserCount(userCountInside, userCountOutside, userCountInactive);
|
||||
updateHeaderCurrentLocation(currentLocationData);
|
||||
@@ -825,7 +825,7 @@ define([
|
||||
|
||||
Util.showNotify({title: 'Logged out', text: data.reason, type: 'error'}, false);
|
||||
|
||||
// remove map -------------------------------------------------------
|
||||
// remove map ---------------------------------------------------------------------------------------------
|
||||
Util.getMapModule().velocity('fadeOut', {
|
||||
duration: 300,
|
||||
complete: function(){
|
||||
@@ -933,7 +933,7 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
// check for character/ship changes ---------------------------------------------
|
||||
// check for character/ship changes ---------------------------------------------------------------------------
|
||||
if(
|
||||
userData &&
|
||||
userData.character
|
||||
@@ -953,7 +953,7 @@ define([
|
||||
return data.id;
|
||||
});
|
||||
|
||||
// update user character data ---------------------------------------------------
|
||||
// update user character data ---------------------------------------------------------------------------------
|
||||
if(currentCharactersOptionIds.toString() !== newCharactersOptionIds.toString()){
|
||||
|
||||
let currentCharacterChanged = false;
|
||||
@@ -976,7 +976,7 @@ define([
|
||||
userInfoElement.data('characterOptionIds', newCharactersOptionIds);
|
||||
}
|
||||
|
||||
// update user ship data --------------------------------------------------------
|
||||
// update user ship data --------------------------------------------------------------------------------------
|
||||
if(currentShipId !== newShipData.typeId){
|
||||
// set new data for next check
|
||||
userShipElement.data('shipData', newShipData);
|
||||
@@ -1058,37 +1058,46 @@ define([
|
||||
};
|
||||
|
||||
/**
|
||||
* update the "current location" element in head
|
||||
* update the "current location" link element in head
|
||||
* @param locationData
|
||||
*/
|
||||
let updateHeaderCurrentLocation = function(locationData){
|
||||
let currentLocationElement = $('#' + Util.config.headCurrentLocationId);
|
||||
let linkElement = currentLocationElement.find('a');
|
||||
let textElement = linkElement.find('span');
|
||||
let updateHeaderCurrentLocation = locationData => {
|
||||
let systemId = locationData.id || 0;
|
||||
let systemName = locationData.name || false;
|
||||
|
||||
let tempSystemName = (locationData.currentSystemName) ? locationData.currentSystemName : false;
|
||||
let tempSystemId = (locationData.currentSystemId) ? locationData.currentSystemId : 0;
|
||||
let currentLocationData = Util.getCurrentLocationData();
|
||||
|
||||
if(
|
||||
linkElement.data('systemName') !== tempSystemName ||
|
||||
linkElement.data('systemId') !== tempSystemId
|
||||
currentLocationData.name !== systemName ||
|
||||
currentLocationData.id !== systemId
|
||||
){
|
||||
linkElement.data('systemName', tempSystemName);
|
||||
linkElement.data('systemId', tempSystemId);
|
||||
linkElement.toggleClass('disabled', !tempSystemId);
|
||||
Util.setCurrentLocationData(systemId, systemName);
|
||||
|
||||
if(tempSystemName !== false){
|
||||
textElement.text(locationData.currentSystemName);
|
||||
let currentLocationElement = $('#' + Util.config.headCurrentLocationId);
|
||||
let linkElement = currentLocationElement.find('a');
|
||||
linkElement.toggleClass('disabled', !systemId);
|
||||
|
||||
if(systemName !== false){
|
||||
linkElement.find('span').text(locationData.name);
|
||||
currentLocationElement.velocity('fadeIn', {duration: Init.animationSpeed.headerLink});
|
||||
}else{
|
||||
if(currentLocationElement.is(':visible')){
|
||||
currentLocationElement.velocity('fadeOut', {duration: Init.animationSpeed.headerLink});
|
||||
}
|
||||
}
|
||||
|
||||
// auto select current system -----------------------------------------------------------------------------
|
||||
let userData = Util.getCurrentUserData();
|
||||
|
||||
if(
|
||||
Boolean(Util.getObjVal(Init, 'character.autoLocationSelect')) &&
|
||||
Util.getObjVal(userData, 'character.selectLocation')
|
||||
){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: systemId, forceSelect: false});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* shows a test notification for desktop messages
|
||||
*/
|
||||
|
||||
@@ -55,6 +55,7 @@ define([
|
||||
formErrorContainerClass: Util.config.formErrorContainerClass,
|
||||
ccpImageServer: Init.url.ccpImageServer,
|
||||
roleLabel: Util.getLabelByRole(Util.getObjVal(Util.getCurrentUserData(), 'character.role')).prop('outerHTML'),
|
||||
characterAutoLocationSelectEnabled: Boolean(Util.getObjVal(Init, 'character.autoLocationSelect'))
|
||||
};
|
||||
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
@@ -307,7 +307,7 @@ define([
|
||||
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
|
||||
// select system
|
||||
$(cell).on('click', function(e){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: rowData.id });
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: rowData.id});
|
||||
});
|
||||
}
|
||||
},{
|
||||
@@ -597,7 +597,7 @@ define([
|
||||
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
|
||||
// select system
|
||||
$(cell).on('click', function(e){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: rowData.source.id });
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: rowData.source.id});
|
||||
});
|
||||
}
|
||||
},{
|
||||
@@ -615,7 +615,7 @@ define([
|
||||
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
|
||||
// select system
|
||||
$(cell).on('click', function(e){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: rowData.target.id });
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: rowData.target.id});
|
||||
});
|
||||
}
|
||||
},{
|
||||
|
||||
@@ -168,7 +168,7 @@ define([
|
||||
class: 'pf-link',
|
||||
html: connectionData.sourceAlias + ' '
|
||||
}).on('click', function(){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: connectionData.source });
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: connectionData.source});
|
||||
}),
|
||||
$('<span>', {
|
||||
class: [config.connectionInfoTableLabelSourceClass].join(' ')
|
||||
@@ -183,7 +183,7 @@ define([
|
||||
class: 'pf-link',
|
||||
html: ' ' + connectionData.targetAlias
|
||||
}).on('click', function(){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: connectionData.target });
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: connectionData.target});
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
@@ -39,7 +39,7 @@ define([
|
||||
// description field
|
||||
descriptionAreaClass: 'pf-system-info-description-area', // class for "description" area
|
||||
addDescriptionButtonClass: 'pf-system-info-description-button', // class for "add description" button
|
||||
descriptionTextareaElementClass: 'pf-system-info-description', // class for "description" textarea element (xEditable)
|
||||
descriptionTextareaElementClass: 'pf-system-info-description', // class for "description" textarea element (Summernote)
|
||||
|
||||
// fonts
|
||||
fontTriglivianClass: 'pf-triglivian', // class for "Triglivian" names (e.g. Abyssal systems)
|
||||
@@ -177,6 +177,7 @@ define([
|
||||
descriptionAreaClass: config.descriptionAreaClass,
|
||||
descriptionButtonClass: config.addDescriptionButtonClass,
|
||||
descriptionTextareaClass: config.descriptionTextareaElementClass,
|
||||
summernoteClass: Util.config.summernoteClass,
|
||||
systemNameClass: () => {
|
||||
return (val, render) => {
|
||||
return render(val) === 'A' ? config.fontTriglivianClass : '';
|
||||
@@ -298,7 +299,7 @@ define([
|
||||
},
|
||||
callbacks: {
|
||||
onInit: function(context){
|
||||
// make editable field a big larger
|
||||
// make editable field a bit larger
|
||||
context.editable.css('height', '150px');
|
||||
|
||||
// set default background color
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/console',
|
||||
'conf/system_effect',
|
||||
'conf/signature_type',
|
||||
'bootbox',
|
||||
@@ -18,7 +19,7 @@ define([
|
||||
'bootstrapConfirmation',
|
||||
'bootstrapToggle',
|
||||
'select2'
|
||||
], ($, Init, SystemEffect, SignatureType, bootbox, localforage) => {
|
||||
], ($, Init, Con, SystemEffect, SignatureType, bootbox, localforage) => {
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -83,6 +84,9 @@ define([
|
||||
popoverSmallClass: 'pf-popover-small', // class for small "popover"
|
||||
popoverCharacterClass: 'pf-popover-character', // class for character "popover"
|
||||
|
||||
// Summernote
|
||||
summernoteClass: 'pf-summernote', // class for Summernote "WYSIWYG" elements
|
||||
|
||||
// help
|
||||
helpDefaultClass: 'pf-help-default', // class for "help" tooltip elements
|
||||
helpClass: 'pf-help', // class for "help" tooltip elements
|
||||
@@ -878,9 +882,7 @@ define([
|
||||
/**
|
||||
* show current program version information in browser console
|
||||
*/
|
||||
let showVersionInfo = () => {
|
||||
console.info('PATHFINDER ' + getVersion());
|
||||
};
|
||||
let showVersionInfo = () => Con.showVersionInfo(getVersion());
|
||||
|
||||
/**
|
||||
* polyfill for "passive" events
|
||||
@@ -2771,16 +2773,28 @@ define([
|
||||
return Init.currentSystemData;
|
||||
};
|
||||
|
||||
/**
|
||||
* set current location data
|
||||
* -> system data where current user is located
|
||||
* @param systemId
|
||||
* @param systemName
|
||||
*/
|
||||
let setCurrentLocationData = (systemId, systemName) => {
|
||||
let locationLink = $('#' + config.headCurrentLocationId).find('a');
|
||||
locationLink.data('systemId', systemId);
|
||||
locationLink.data('systemName', systemName);
|
||||
};
|
||||
|
||||
/**
|
||||
* get current location data
|
||||
* -> system data where current user is located
|
||||
* @returns {{id: *, name: *}}
|
||||
*/
|
||||
let getCurrentLocationData = () => {
|
||||
let currentLocationLink = $('#' + config.headCurrentLocationId).find('a');
|
||||
let locationLink = $('#' + config.headCurrentLocationId).find('a');
|
||||
return {
|
||||
id: currentLocationLink.data('systemId'),
|
||||
name: currentLocationLink.data('systemName')
|
||||
id: locationLink.data('systemId') || 0,
|
||||
name: locationLink.data('systemName') || false
|
||||
};
|
||||
};
|
||||
|
||||
@@ -3012,6 +3026,13 @@ define([
|
||||
return Array.from(doc.body.childNodes).some(node => node.nodeType === 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* checks if a given object is a DOM element
|
||||
* @param obj
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let isDomElement = obj => !!(obj && obj.nodeType === 1);
|
||||
|
||||
/**
|
||||
* get deep json object value if exists
|
||||
* -> e.g. key = 'first.last.third' string
|
||||
@@ -3189,6 +3210,7 @@ define([
|
||||
getCurrentCharacterId: getCurrentCharacterId,
|
||||
setCurrentSystemData: setCurrentSystemData,
|
||||
getCurrentSystemData: getCurrentSystemData,
|
||||
setCurrentLocationData: setCurrentLocationData,
|
||||
getCurrentLocationData: getCurrentLocationData,
|
||||
getCurrentUserInfo: getCurrentUserInfo,
|
||||
getCurrentCharacterLog: getCurrentCharacterLog,
|
||||
@@ -3216,6 +3238,7 @@ define([
|
||||
htmlEncode: htmlEncode,
|
||||
htmlDecode: htmlDecode,
|
||||
isValidHtml: isValidHtml,
|
||||
isDomElement: isDomElement,
|
||||
getObjVal: getObjVal,
|
||||
redirect: redirect,
|
||||
logout: logout,
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
215
public/js/v1.4.4/app/console.js
Normal file
215
public/js/v1.4.4/app/console.js
Normal file
@@ -0,0 +1,215 @@
|
||||
/**
|
||||
* Console module
|
||||
* -> extends default window.console log object
|
||||
*/
|
||||
|
||||
define([], () => {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* init custom window.console object
|
||||
* -> extend console obj with custom methods for styling and logging
|
||||
*/
|
||||
let initConsole = () => {
|
||||
|
||||
window.console = (origConsole => {
|
||||
// save orig methods for byPassing args to original methods
|
||||
let log = origConsole.log;
|
||||
let info = origConsole.info;
|
||||
let warn = origConsole.warn;
|
||||
let error = origConsole.error;
|
||||
|
||||
let styles = {
|
||||
'indentDefault': {
|
||||
'padding-left': '3px'
|
||||
},
|
||||
'global': {
|
||||
'font-weight': 500,
|
||||
'font-size': '11px',
|
||||
'line-height': '19px',
|
||||
'font-family': '"Fira Code", "Lucida Console"',
|
||||
},
|
||||
'ok': {
|
||||
'color': '#5cb85c'
|
||||
},
|
||||
'log': {
|
||||
'color': '#adadad'
|
||||
},
|
||||
'info': {
|
||||
'color': '#428bca'
|
||||
},
|
||||
'warn': {
|
||||
'color': '#ffdd9e'
|
||||
},
|
||||
'error': {
|
||||
'color': '#ff8080'
|
||||
},
|
||||
'pf': {
|
||||
'color': '#568a89'
|
||||
},
|
||||
'brand': {
|
||||
'color': '#375959',
|
||||
'line-height': '35px',
|
||||
'font-size': '25px'
|
||||
}
|
||||
};
|
||||
|
||||
let placeholders = {
|
||||
'%s': {
|
||||
'style': ['color: #e93f3b; font-style: italic', 'color: inherit']
|
||||
},
|
||||
'%i': {
|
||||
'style': ['color: #9980ff', 'color: inherit'],
|
||||
},
|
||||
'%d': {
|
||||
'style': ['color: #9980ff', 'color: inherit']
|
||||
},
|
||||
'%f': {
|
||||
'style': ['color: #9980ff', 'color: inherit']
|
||||
},
|
||||
'%o': {
|
||||
'style': ['', '']
|
||||
},
|
||||
'%O': {
|
||||
'style': ['', '']
|
||||
}
|
||||
};
|
||||
|
||||
let findPlaceholders = str => {
|
||||
let exp = new RegExp(Object.keys(placeholders).join('|'), 'g');
|
||||
let matches = str.match(exp);
|
||||
return matches ? matches : [];
|
||||
};
|
||||
|
||||
let addStylePlaceholder = str => {
|
||||
let exp = new RegExp(Object.keys(placeholders).join('|'), 'g');
|
||||
|
||||
return str.replace(exp, function(matched){
|
||||
return '%c' + matched + '%c';
|
||||
});
|
||||
};
|
||||
|
||||
let getStyleByPlaceholder = (placeholder, clear = false) => {
|
||||
let css = '';
|
||||
if(placeholders.hasOwnProperty(placeholder)){
|
||||
css = placeholders[placeholder].style[clear ? 1 : 0];
|
||||
}
|
||||
return css;
|
||||
};
|
||||
|
||||
let getStyleByLogType = (logType, props = []) => {
|
||||
let css = '';
|
||||
if(styles.hasOwnProperty(logType)){
|
||||
css = Object.keys(styles[logType])
|
||||
.filter(prop => props.length ? props.includes(prop) : true)
|
||||
.reduce((css, prop,i, affe) => {
|
||||
css += prop + ':' + styles[logType][prop] + ';';
|
||||
return css;
|
||||
}, '');
|
||||
}
|
||||
return css;
|
||||
};
|
||||
|
||||
let setLineStyleByLogType = (logType, args) => {
|
||||
if(args.length){
|
||||
let lineStyle = getStyleByLogType('global') + getStyleByLogType(logType);
|
||||
lineStyle += ['ok', 'log', 'info', 'pf'].includes(logType) ? getStyleByLogType('indentDefault') : '';
|
||||
let bullet = ['ok', 'log', 'info', 'pf'].includes(logType) ? '●' : '';
|
||||
|
||||
if(typeof args[0] === 'string'){
|
||||
// prepend placeholder to existing message
|
||||
args[0] = '%c' + bullet + ' ' + args[0];
|
||||
}else{
|
||||
// prepend placeholder as new message
|
||||
args.splice(0, 0, '%c' + bullet + ' ' + logType + ':');
|
||||
}
|
||||
// set line style as 2nd argument
|
||||
args.splice(1, 0, lineStyle);
|
||||
}
|
||||
};
|
||||
|
||||
let setMessageStyleByLogType = (logType, args) => {
|
||||
if(typeof args[0] === 'string') {
|
||||
let placeholdersFound = findPlaceholders(args[0]);
|
||||
let placeholderCount = placeholdersFound.length;
|
||||
|
||||
// add c% placeholders around other placeholders
|
||||
args[0] = addStylePlaceholder(args[0]);
|
||||
|
||||
// add style args for c% placeholders
|
||||
let placeholderIndex = 0;
|
||||
let argIndexStart = 1;
|
||||
let argIndexEnd = argIndexStart + placeholderCount;
|
||||
let argIndexOffset = 0;
|
||||
for (let argIndex = argIndexStart; argIndex < argIndexEnd; argIndex++) {
|
||||
args.splice(argIndex + argIndexOffset, 0, getStyleByPlaceholder(placeholdersFound[placeholderIndex]));
|
||||
argIndexOffset += 2;
|
||||
args.splice(argIndex + argIndexOffset, 0, getStyleByPlaceholder(placeholdersFound[placeholderIndex], true) + ';' + getStyleByLogType('global') + getStyleByLogType(logType));
|
||||
placeholderIndex++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
origConsole.ok = (...args) => {
|
||||
setMessageStyleByLogType('ok', args);
|
||||
setLineStyleByLogType('ok', args);
|
||||
info.apply(origConsole, args);
|
||||
};
|
||||
|
||||
origConsole.info = (...args) => {
|
||||
setMessageStyleByLogType('info', args);
|
||||
setLineStyleByLogType('info', args);
|
||||
info.apply(origConsole, args);
|
||||
};
|
||||
|
||||
origConsole.log = (...args) => {
|
||||
setMessageStyleByLogType('log', args);
|
||||
setLineStyleByLogType('log', args);
|
||||
log.apply(origConsole, args);
|
||||
};
|
||||
|
||||
origConsole.warn = (...args) => {
|
||||
setMessageStyleByLogType('warn', args);
|
||||
setLineStyleByLogType('warn', args);
|
||||
warn.apply(origConsole, args);
|
||||
};
|
||||
|
||||
origConsole.error = (...args) => {
|
||||
setMessageStyleByLogType('error', args);
|
||||
setLineStyleByLogType('error', args);
|
||||
error.apply(origConsole, args);
|
||||
};
|
||||
|
||||
origConsole.pf = (...args) => {
|
||||
setMessageStyleByLogType('pf', args);
|
||||
setLineStyleByLogType('pf', args);
|
||||
info.apply(origConsole, args);
|
||||
};
|
||||
|
||||
origConsole.brand = (...args) => {
|
||||
setMessageStyleByLogType('brand', args);
|
||||
setLineStyleByLogType('brand', args);
|
||||
info.apply(origConsole, args);
|
||||
};
|
||||
|
||||
return origConsole;
|
||||
})(window.console);
|
||||
};
|
||||
|
||||
initConsole();
|
||||
|
||||
/**
|
||||
* show current program version information console
|
||||
* @param version
|
||||
*/
|
||||
let showVersionInfo = (version) => {
|
||||
console.ok('%c PATHFINDER',
|
||||
'color: #477372; font-size: 25px; margin-left: 10px; line-height: 100px; text-shadow: 1px 1px 0 #212C30; ' +
|
||||
'background: url(https://i.imgur.com/1Gw8mjL.png) no-repeat;');
|
||||
console.pf('Release: %s', version);
|
||||
};
|
||||
|
||||
return {
|
||||
showVersionInfo: showVersionInfo
|
||||
};
|
||||
});
|
||||
@@ -1495,7 +1495,7 @@ define([
|
||||
hiddenOptions.push('delete_system');
|
||||
}
|
||||
|
||||
let mapElement = component.parents('.' + config.mapClass);
|
||||
let mapElement = component.closest('.' + config.mapClass);
|
||||
if( !mapElement.find('.' + config.systemActiveClass).length ){
|
||||
hiddenOptions.push('find_route');
|
||||
}
|
||||
@@ -1827,7 +1827,7 @@ define([
|
||||
let single = function(e){
|
||||
// check if click was performed on "popover" (x-editable)
|
||||
let popoverClick = false;
|
||||
if( $(e.target).parents('.popover').length ){
|
||||
if( $(e.target).closest('.popover').length ){
|
||||
popoverClick = true;
|
||||
}
|
||||
|
||||
@@ -2014,7 +2014,7 @@ define([
|
||||
// register all available connection types ----------------------------------------------------------------
|
||||
newJsPlumbInstance.registerConnectionTypes(globalMapConfig.connectionTypes);
|
||||
|
||||
// event after a new connection is established --------------------------
|
||||
// event after a new connection is established ------------------------------------------------------------
|
||||
newJsPlumbInstance.bind('connection', function(info, e){
|
||||
// set connection observer
|
||||
setConnectionObserver(newJsPlumbInstance, info.connection);
|
||||
@@ -2114,6 +2114,54 @@ define([
|
||||
return MapUtil.getMapInstance(mapId);
|
||||
};
|
||||
|
||||
/**
|
||||
* check if there is an focus() element found as parent of tabContentElement
|
||||
* -> or if there is any other active UI element found (e.g. dialog, xEditable, Summernote)
|
||||
* @param tabContentElement
|
||||
* @returns {*}
|
||||
*/
|
||||
let systemFormsActive = (tabContentElement) => {
|
||||
let activeNode = null;
|
||||
if(tabContentElement.length){
|
||||
// tabContentElement exists ...
|
||||
tabContentElement = tabContentElement[0];
|
||||
|
||||
// ... check for current active/focus() element and is not the default <body> element ...
|
||||
if(
|
||||
Util.isDomElement(document.activeElement) &&
|
||||
document.activeElement !== document.body
|
||||
){
|
||||
let activeElementTagName = document.activeElement.tagName.toLocaleLowerCase();
|
||||
|
||||
// ... check for active form elements ...
|
||||
let isFormElement = ['input', 'select', 'textarea'].includes(activeElementTagName);
|
||||
let isChildElement = tabContentElement.contains(document.activeElement);
|
||||
|
||||
if(isFormElement && isChildElement){
|
||||
activeNode = activeElementTagName;
|
||||
}else{
|
||||
// ... check for open dialogs/xEditable elements ...
|
||||
if(Util.isDomElement(document.querySelector('.bootbox'))){
|
||||
activeNode = 'dialogOpen';
|
||||
}else if(Util.isDomElement(document.querySelector('.editable-open'))){
|
||||
activeNode = 'xEditableOpen';
|
||||
}else{
|
||||
// ... check for open Summernote editor
|
||||
let summernoteElement = tabContentElement.querySelector('.' + Util.config.summernoteClass);
|
||||
if(
|
||||
Util.isDomElement(summernoteElement) &&
|
||||
typeof $(summernoteElement).data().summernote === 'object'
|
||||
){
|
||||
activeNode = 'SummernoteOpen';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return activeNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* set observer for a map container
|
||||
* @param map
|
||||
@@ -2484,17 +2532,30 @@ define([
|
||||
|
||||
// triggered from "header" link (if user is active in one of the systems)
|
||||
mapContainer.on('pf:menuSelectSystem', function(e, data){
|
||||
let tempMapContainer = $(this);
|
||||
let systemId = MapUtil.getSystemId(tempMapContainer.data('id'), data.systemId);
|
||||
let system = $(this).find('#' + systemId);
|
||||
let mapElement = $(this);
|
||||
let systemId = MapUtil.getSystemId(mapElement.data('id'), data.systemId);
|
||||
let system = mapElement.find('#' + systemId);
|
||||
|
||||
if(system.length === 1){
|
||||
// scroll to system
|
||||
let tempMapWrapper = tempMapContainer.parents('.' + config.mapWrapperClass);
|
||||
tempMapWrapper.mCustomScrollbar('scrollTo', system);
|
||||
// system found on map ...
|
||||
let select = Util.getObjVal(data, 'forceSelect') !== false;
|
||||
|
||||
// select system
|
||||
MapUtil.showSystemInfo(map, system);
|
||||
if(!select){
|
||||
// ... select is NOT "forced" -> auto select system on jump
|
||||
let activeElement = systemFormsActive(MapUtil.getTabContentElementByMapElement(system));
|
||||
if(activeElement !== null){
|
||||
console.info('Skip auto select systemId %i. Reason: %o', data.systemId, activeElement);
|
||||
}else{
|
||||
select = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(select){
|
||||
let mapWrapper = mapElement.closest('.' + config.mapWrapperClass);
|
||||
mapWrapper.scrollToSystem(MapUtil.getSystemPosition(system));
|
||||
// select system
|
||||
MapUtil.showSystemInfo(map, system);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2595,118 +2656,125 @@ define([
|
||||
/**
|
||||
* updates all systems on map with current user Data (all users on this map)
|
||||
* update the Data of the user that is currently viewing the map (if available)
|
||||
* @param mapElement
|
||||
* @param userData
|
||||
* @returns {boolean}
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
$.fn.updateUserData = function(userData){
|
||||
let returnStatus = true;
|
||||
let updateUserData = (mapElement, userData) => {
|
||||
|
||||
// get new map instance or load existing
|
||||
let map = getMapInstance(userData.config.id);
|
||||
|
||||
let mapElement = map.getContainer();
|
||||
|
||||
// container must exist! otherwise systems can not be updated
|
||||
if(mapElement !== undefined){
|
||||
mapElement = $(mapElement);
|
||||
|
||||
// check if map is frozen
|
||||
if(mapElement.data('frozen') === true){
|
||||
return returnStatus;
|
||||
}
|
||||
|
||||
// compact/small system layout or not
|
||||
let compactView = mapElement.hasClass(MapUtil.config.mapCompactClass);
|
||||
|
||||
// get current character log data
|
||||
let characterLogExists = false;
|
||||
let currentCharacterLog = Util.getCurrentCharacterLog();
|
||||
|
||||
// data for header update
|
||||
let headerUpdateData = {
|
||||
mapId: userData.config.id,
|
||||
userCountInside: 0, // active user on a map
|
||||
userCountOutside: 0, // active user NOT on map
|
||||
userCountInactive: 0 // inactive users (no location)
|
||||
let updateUserDataExecutor = (resolve, reject) => {
|
||||
let payload = {
|
||||
action: 'updateUserData'
|
||||
};
|
||||
|
||||
if(
|
||||
currentCharacterLog &&
|
||||
currentCharacterLog.system
|
||||
){
|
||||
characterLogExists = true;
|
||||
headerUpdateData.currentSystemName = currentCharacterLog.system.name;
|
||||
}
|
||||
// get new map instance or load existing
|
||||
let map = getMapInstance(userData.config.id);
|
||||
let mapElement = map.getContainer();
|
||||
|
||||
// check if current user was found on the map
|
||||
let currentUserOnMap = false;
|
||||
// container must exist! otherwise systems can not be updated
|
||||
if(mapElement !== undefined){
|
||||
mapElement = $(mapElement);
|
||||
|
||||
// get all systems
|
||||
let systems = mapElement.find('.' + config.systemClass);
|
||||
|
||||
for(let i = 0; i < systems.length; i++){
|
||||
// get user Data for System
|
||||
|
||||
let system = $( systems[i] );
|
||||
|
||||
let systemId = $(system).data('systemId');
|
||||
|
||||
let tempUserData = null;
|
||||
|
||||
// check if user is currently in "this" system
|
||||
let currentUserIsHere = false;
|
||||
|
||||
let j = userData.data.systems.length;
|
||||
|
||||
// search backwards to avoid decrement the counter after splice()
|
||||
while(j--){
|
||||
let systemData = userData.data.systems[j];
|
||||
|
||||
// check if any user is in this system
|
||||
if(systemId === systemData.id){
|
||||
tempUserData = systemData;
|
||||
|
||||
// add "user count" to "total map user count"
|
||||
headerUpdateData.userCountInside += tempUserData.user.length;
|
||||
|
||||
// remove system from "search" array -> speed up loop
|
||||
userData.data.systems.splice(j, 1);
|
||||
}
|
||||
// no user update for 'frozen' maps...
|
||||
if(mapElement.data('frozen') === true){
|
||||
return resolve(payload);
|
||||
}
|
||||
|
||||
// the current user can only be in a single system ----------------------------------------------------
|
||||
// compact/small system layout or not
|
||||
let compactView = mapElement.hasClass(MapUtil.config.mapCompactClass);
|
||||
|
||||
// get current character log data
|
||||
let characterLogExists = false;
|
||||
let currentCharacterLog = Util.getCurrentCharacterLog();
|
||||
|
||||
// data for header update
|
||||
let headerUpdateData = {
|
||||
mapId: userData.config.id,
|
||||
userCountInside: 0, // active user on a map
|
||||
userCountOutside: 0, // active user NOT on map
|
||||
userCountInactive: 0, // inactive users (no location)
|
||||
currentLocation: {
|
||||
id: 0, // systemId for current active user
|
||||
name: false // systemName for current active user
|
||||
}
|
||||
};
|
||||
|
||||
if(
|
||||
characterLogExists &&
|
||||
currentCharacterLog.system.id === systemId
|
||||
currentCharacterLog &&
|
||||
currentCharacterLog.system
|
||||
){
|
||||
if( !currentUserOnMap ){
|
||||
currentUserIsHere = true;
|
||||
currentUserOnMap = true;
|
||||
characterLogExists = true;
|
||||
headerUpdateData.currentLocation.name = currentCharacterLog.system.name;
|
||||
}
|
||||
|
||||
// set current location data for header update
|
||||
headerUpdateData.currentSystemId = $(system).data('id');
|
||||
headerUpdateData.currentSystemName = currentCharacterLog.system.name;
|
||||
// check if current user was found on the map
|
||||
let currentUserOnMap = false;
|
||||
|
||||
// get all systems
|
||||
let systems = mapElement.find('.' + config.systemClass);
|
||||
|
||||
for(let system of systems){
|
||||
system = $(system);
|
||||
let systemId = system.data('systemId');
|
||||
let tempUserData = null;
|
||||
|
||||
// check if user is currently in "this" system
|
||||
let currentUserIsHere = false;
|
||||
|
||||
let j = userData.data.systems.length;
|
||||
|
||||
// search backwards to avoid decrement the counter after splice()
|
||||
while(j--){
|
||||
let systemData = userData.data.systems[j];
|
||||
|
||||
// check if any user is in this system
|
||||
if(systemId === systemData.id){
|
||||
tempUserData = systemData;
|
||||
|
||||
// add "user count" to "total map user count"
|
||||
headerUpdateData.userCountInside += tempUserData.user.length;
|
||||
|
||||
// remove system from "search" array -> speed up loop
|
||||
userData.data.systems.splice(j, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// the current user can only be in a single system ------------------------------------------------
|
||||
if(
|
||||
characterLogExists &&
|
||||
currentCharacterLog.system.id === systemId
|
||||
){
|
||||
if( !currentUserOnMap ){
|
||||
currentUserIsHere = true;
|
||||
currentUserOnMap = true;
|
||||
|
||||
// set current location data for header update
|
||||
headerUpdateData.currentLocation.id = system.data('id');
|
||||
headerUpdateData.currentLocation.name = currentCharacterLog.system.name;
|
||||
}
|
||||
}
|
||||
|
||||
system.updateSystemUserData(map, tempUserData, currentUserIsHere, {compactView: compactView});
|
||||
}
|
||||
|
||||
// users who are not in any map system ----------------------------------------------------------------
|
||||
for(let systemData of userData.data.systems){
|
||||
// users without location are grouped in systemId: 0
|
||||
if(systemData.id){
|
||||
headerUpdateData.userCountOutside += systemData.user.length;
|
||||
}else{
|
||||
headerUpdateData.userCountInactive += systemData.user.length;
|
||||
}
|
||||
}
|
||||
|
||||
system.updateSystemUserData(map, tempUserData, currentUserIsHere, {compactView: compactView});
|
||||
// trigger document event -> update header
|
||||
$(document).trigger('pf:updateHeaderMapData', headerUpdateData);
|
||||
}
|
||||
|
||||
// users who are not in any map system --------------------------------------------------------------------
|
||||
for(let i = 0; i < userData.data.systems.length; i++){
|
||||
// users without location are grouped in systemId: 0
|
||||
if(userData.data.systems[i].id){
|
||||
headerUpdateData.userCountOutside += userData.data.systems[i].user.length;
|
||||
}else{
|
||||
headerUpdateData.userCountInactive += userData.data.systems[i].user.length;
|
||||
}
|
||||
}
|
||||
resolve(payload);
|
||||
};
|
||||
|
||||
// trigger document event -> update header
|
||||
$(document).trigger('pf:updateHeaderMapData', headerUpdateData);
|
||||
}
|
||||
|
||||
return returnStatus;
|
||||
return new Promise(updateUserDataExecutor);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2851,17 +2919,7 @@ define([
|
||||
updated: parseInt( system.data('updated') )
|
||||
};
|
||||
systemData.userCount = (system.data('userCount') ? parseInt( system.data('userCount') ) : 0);
|
||||
|
||||
// position ---------------------------------------------------------------------------------------------------
|
||||
let positionData = {};
|
||||
let currentX = system.css('left');
|
||||
let currentY = system.css('top');
|
||||
|
||||
// remove 'px'
|
||||
positionData.x = parseInt( currentX.substring(0, currentX.length - 2) );
|
||||
positionData.y = parseInt( currentY.substring(0, currentY.length - 2) );
|
||||
|
||||
systemData.position = positionData;
|
||||
systemData.position = MapUtil.getSystemPosition(system);
|
||||
|
||||
return systemData;
|
||||
};
|
||||
@@ -2982,6 +3040,7 @@ define([
|
||||
return {
|
||||
getMapInstance: getMapInstance,
|
||||
loadMap: loadMap,
|
||||
updateUserData: updateUserData,
|
||||
saveSystemCallback: saveSystemCallback
|
||||
};
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ define([
|
||||
};
|
||||
|
||||
/**
|
||||
* scroll to a specific position in the map
|
||||
* scroll to a specific position on map
|
||||
* demo: http://manos.malihu.gr/repository/custom-scrollbar/demo/examples/scrollTo_demo.html
|
||||
* @param position
|
||||
*/
|
||||
@@ -79,4 +79,31 @@ define([
|
||||
$(this).mCustomScrollbar('scrollTo', position);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* scroll to a specific system on map
|
||||
* -> subtract some offset for tooltips/connections
|
||||
* @param position
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.scrollToSystem = function(position){
|
||||
position = getOffsetPosition(position, {x: -15, y: -35});
|
||||
return this.each(function(){
|
||||
$(this).mCustomScrollbar('scrollTo', position);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* add/subtract offset coordinates from position
|
||||
* -> no negative values returned
|
||||
* @param position
|
||||
* @param offset
|
||||
* @returns {{x: number, y: number}}
|
||||
*/
|
||||
let getOffsetPosition = (position, offset) => {
|
||||
return {
|
||||
x: Math.max(0, position.x + offset.x),
|
||||
y: Math.max(0, position.y + offset.y)
|
||||
};
|
||||
};
|
||||
});
|
||||
@@ -482,7 +482,7 @@ define([
|
||||
* @param label
|
||||
* @returns {string}
|
||||
*/
|
||||
let getEndpointOverlayContent = (label) => {
|
||||
let getEndpointOverlayContent = label => {
|
||||
let newLabel = '';
|
||||
let colorClass = 'txt-color-grayLighter';
|
||||
|
||||
@@ -508,17 +508,14 @@ define([
|
||||
* @param element
|
||||
* @returns {*}
|
||||
*/
|
||||
let getTabContentElementByMapElement = (element) => {
|
||||
let tabContentElement = $(element).parents('.' + config.mapTabContentClass);
|
||||
return tabContentElement;
|
||||
};
|
||||
let getTabContentElementByMapElement = element => $(element).closest('.' + config.mapTabContentClass);
|
||||
|
||||
/**
|
||||
* checks if there is an "active" connection on a map
|
||||
* @param map
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let hasActiveConnection = (map) => {
|
||||
let hasActiveConnection = map => {
|
||||
let activeConnections = getConnectionsByType(map, 'active');
|
||||
return activeConnections.length > 0;
|
||||
};
|
||||
@@ -1203,6 +1200,21 @@ define([
|
||||
return new Promise(setMapDefaultOptionsExecutor);
|
||||
};
|
||||
|
||||
/**
|
||||
* get system coordinates from systemElement
|
||||
* @param system
|
||||
* @returns {{x: number, y: number}}
|
||||
*/
|
||||
let getSystemPosition = system => {
|
||||
let x = system.css('left');
|
||||
let y = system.css('top');
|
||||
|
||||
return {
|
||||
x: parseInt(x.substring(0, x.length - 2)),
|
||||
y: parseInt(y.substring(0, y.length - 2))
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* scroll map to default (stored) x/y coordinates
|
||||
* @param mapElement
|
||||
@@ -1755,6 +1767,7 @@ define([
|
||||
deleteLocalData: deleteLocalData,
|
||||
visualizeMap: visualizeMap,
|
||||
setMapDefaultOptions: setMapDefaultOptions,
|
||||
getSystemPosition: getSystemPosition,
|
||||
scrollToDefaultPosition: scrollToDefaultPosition,
|
||||
getSystemId: getSystemId,
|
||||
checkRight: checkRight,
|
||||
|
||||
@@ -143,6 +143,7 @@ define([
|
||||
Init.characterStatus = response.characterStatus;
|
||||
Init.routes = response.routes;
|
||||
Init.url = response.url;
|
||||
Init.character = response.character;
|
||||
Init.slack = response.slack;
|
||||
Init.discord = response.discord;
|
||||
Init.structureStatus = response.structureStatus;
|
||||
@@ -308,10 +309,10 @@ define([
|
||||
.then(payload => Promise.all([initMapModule(payload[0]), initMapWorker(payload[1])]))
|
||||
.then(payload => {
|
||||
// mapModule initialized and WebSocket configuration working
|
||||
console.info('%s() complete! command: "%s"; syncStatus: "%s"',
|
||||
payload[1].action,
|
||||
payload[1].data.command,
|
||||
payload[1].data.syncStatus
|
||||
console.ok('Client syncStatus: %s. %O resolved by command: %s!',
|
||||
payload[1].data.syncStatus,
|
||||
payload[1].action + '()',
|
||||
payload[1].data.command
|
||||
);
|
||||
})
|
||||
.catch(payload => {
|
||||
@@ -322,10 +323,10 @@ define([
|
||||
break;
|
||||
case 'initMapWorker':
|
||||
// WebSocket not working -> no error here -> fallback to Ajax
|
||||
console.warn('%s() rejects Promise. command: "%s"; syncStatus: "%s", payload: %o',
|
||||
payload.action,
|
||||
payload.data.command,
|
||||
console.info('Client syncStatus: %s. %O rejected by command: %s! payload: %o',
|
||||
payload.data.syncStatus,
|
||||
payload.action + '()',
|
||||
payload.data.command,
|
||||
payload.data
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -458,7 +458,7 @@ define([
|
||||
mapElement.trigger('pf:updateLocal', currentMapUserData);
|
||||
|
||||
// update map with current user data
|
||||
mapElement.updateUserData(currentMapUserData);
|
||||
Map.updateUserData(mapElement, currentMapUserData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -491,7 +491,7 @@ define([
|
||||
|
||||
pageElement.prepend(headRendered);
|
||||
|
||||
// init header =====================================================================
|
||||
// init header ================================================================================================
|
||||
|
||||
// init slide menus
|
||||
let slideMenu = new $.slidebars({
|
||||
@@ -516,7 +516,7 @@ define([
|
||||
|
||||
// current location
|
||||
$('#' + Util.config.headCurrentLocationId).find('a').on('click', function(){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: $(this).data('systemId') });
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: $(this).data('systemId')});
|
||||
});
|
||||
|
||||
// program status
|
||||
@@ -589,7 +589,7 @@ define([
|
||||
|
||||
pageElement.prepend(footerElement);
|
||||
|
||||
// init footer ==================================================
|
||||
// init footer ================================================================================================
|
||||
pageElement.find('.' + config.footerLicenceLinkClass).on('click', function(){
|
||||
//show credits info dialog
|
||||
$.fn.showCreditsDialog();
|
||||
@@ -728,7 +728,7 @@ define([
|
||||
return false;
|
||||
});
|
||||
|
||||
// END menu events =============================================================================
|
||||
// END menu events ============================================================================================
|
||||
|
||||
// global "popover" callback (for all popovers)
|
||||
$('.' + Util.config.popoverTriggerClass).on('hide.bs.popover', function(e){
|
||||
@@ -772,7 +772,7 @@ define([
|
||||
userCountInside = data.userCountInside;
|
||||
userCountOutside = data.userCountOutside;
|
||||
userCountInactive = data.userCountInactive;
|
||||
currentLocationData = data;
|
||||
currentLocationData = data.currentLocation;
|
||||
}
|
||||
updateHeaderActiveUserCount(userCountInside, userCountOutside, userCountInactive);
|
||||
updateHeaderCurrentLocation(currentLocationData);
|
||||
@@ -825,7 +825,7 @@ define([
|
||||
|
||||
Util.showNotify({title: 'Logged out', text: data.reason, type: 'error'}, false);
|
||||
|
||||
// remove map -------------------------------------------------------
|
||||
// remove map ---------------------------------------------------------------------------------------------
|
||||
Util.getMapModule().velocity('fadeOut', {
|
||||
duration: 300,
|
||||
complete: function(){
|
||||
@@ -933,7 +933,7 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
// check for character/ship changes ---------------------------------------------
|
||||
// check for character/ship changes ---------------------------------------------------------------------------
|
||||
if(
|
||||
userData &&
|
||||
userData.character
|
||||
@@ -953,7 +953,7 @@ define([
|
||||
return data.id;
|
||||
});
|
||||
|
||||
// update user character data ---------------------------------------------------
|
||||
// update user character data ---------------------------------------------------------------------------------
|
||||
if(currentCharactersOptionIds.toString() !== newCharactersOptionIds.toString()){
|
||||
|
||||
let currentCharacterChanged = false;
|
||||
@@ -976,7 +976,7 @@ define([
|
||||
userInfoElement.data('characterOptionIds', newCharactersOptionIds);
|
||||
}
|
||||
|
||||
// update user ship data --------------------------------------------------------
|
||||
// update user ship data --------------------------------------------------------------------------------------
|
||||
if(currentShipId !== newShipData.typeId){
|
||||
// set new data for next check
|
||||
userShipElement.data('shipData', newShipData);
|
||||
@@ -1058,37 +1058,46 @@ define([
|
||||
};
|
||||
|
||||
/**
|
||||
* update the "current location" element in head
|
||||
* update the "current location" link element in head
|
||||
* @param locationData
|
||||
*/
|
||||
let updateHeaderCurrentLocation = function(locationData){
|
||||
let currentLocationElement = $('#' + Util.config.headCurrentLocationId);
|
||||
let linkElement = currentLocationElement.find('a');
|
||||
let textElement = linkElement.find('span');
|
||||
let updateHeaderCurrentLocation = locationData => {
|
||||
let systemId = locationData.id || 0;
|
||||
let systemName = locationData.name || false;
|
||||
|
||||
let tempSystemName = (locationData.currentSystemName) ? locationData.currentSystemName : false;
|
||||
let tempSystemId = (locationData.currentSystemId) ? locationData.currentSystemId : 0;
|
||||
let currentLocationData = Util.getCurrentLocationData();
|
||||
|
||||
if(
|
||||
linkElement.data('systemName') !== tempSystemName ||
|
||||
linkElement.data('systemId') !== tempSystemId
|
||||
currentLocationData.name !== systemName ||
|
||||
currentLocationData.id !== systemId
|
||||
){
|
||||
linkElement.data('systemName', tempSystemName);
|
||||
linkElement.data('systemId', tempSystemId);
|
||||
linkElement.toggleClass('disabled', !tempSystemId);
|
||||
Util.setCurrentLocationData(systemId, systemName);
|
||||
|
||||
if(tempSystemName !== false){
|
||||
textElement.text(locationData.currentSystemName);
|
||||
let currentLocationElement = $('#' + Util.config.headCurrentLocationId);
|
||||
let linkElement = currentLocationElement.find('a');
|
||||
linkElement.toggleClass('disabled', !systemId);
|
||||
|
||||
if(systemName !== false){
|
||||
linkElement.find('span').text(locationData.name);
|
||||
currentLocationElement.velocity('fadeIn', {duration: Init.animationSpeed.headerLink});
|
||||
}else{
|
||||
if(currentLocationElement.is(':visible')){
|
||||
currentLocationElement.velocity('fadeOut', {duration: Init.animationSpeed.headerLink});
|
||||
}
|
||||
}
|
||||
|
||||
// auto select current system -----------------------------------------------------------------------------
|
||||
let userData = Util.getCurrentUserData();
|
||||
|
||||
if(
|
||||
Boolean(Util.getObjVal(Init, 'character.autoLocationSelect')) &&
|
||||
Util.getObjVal(userData, 'character.selectLocation')
|
||||
){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: systemId, forceSelect: false});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* shows a test notification for desktop messages
|
||||
*/
|
||||
|
||||
@@ -55,6 +55,7 @@ define([
|
||||
formErrorContainerClass: Util.config.formErrorContainerClass,
|
||||
ccpImageServer: Init.url.ccpImageServer,
|
||||
roleLabel: Util.getLabelByRole(Util.getObjVal(Util.getCurrentUserData(), 'character.role')).prop('outerHTML'),
|
||||
characterAutoLocationSelectEnabled: Boolean(Util.getObjVal(Init, 'character.autoLocationSelect'))
|
||||
};
|
||||
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
@@ -307,7 +307,7 @@ define([
|
||||
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
|
||||
// select system
|
||||
$(cell).on('click', function(e){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: rowData.id });
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: rowData.id});
|
||||
});
|
||||
}
|
||||
},{
|
||||
@@ -597,7 +597,7 @@ define([
|
||||
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
|
||||
// select system
|
||||
$(cell).on('click', function(e){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: rowData.source.id });
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: rowData.source.id});
|
||||
});
|
||||
}
|
||||
},{
|
||||
@@ -615,7 +615,7 @@ define([
|
||||
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
|
||||
// select system
|
||||
$(cell).on('click', function(e){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: rowData.target.id });
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: rowData.target.id});
|
||||
});
|
||||
}
|
||||
},{
|
||||
|
||||
@@ -168,7 +168,7 @@ define([
|
||||
class: 'pf-link',
|
||||
html: connectionData.sourceAlias + ' '
|
||||
}).on('click', function(){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: connectionData.source });
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: connectionData.source});
|
||||
}),
|
||||
$('<span>', {
|
||||
class: [config.connectionInfoTableLabelSourceClass].join(' ')
|
||||
@@ -183,7 +183,7 @@ define([
|
||||
class: 'pf-link',
|
||||
html: ' ' + connectionData.targetAlias
|
||||
}).on('click', function(){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: connectionData.target });
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('SelectSystem', {systemId: connectionData.target});
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
@@ -39,7 +39,7 @@ define([
|
||||
// description field
|
||||
descriptionAreaClass: 'pf-system-info-description-area', // class for "description" area
|
||||
addDescriptionButtonClass: 'pf-system-info-description-button', // class for "add description" button
|
||||
descriptionTextareaElementClass: 'pf-system-info-description', // class for "description" textarea element (xEditable)
|
||||
descriptionTextareaElementClass: 'pf-system-info-description', // class for "description" textarea element (Summernote)
|
||||
|
||||
// fonts
|
||||
fontTriglivianClass: 'pf-triglivian', // class for "Triglivian" names (e.g. Abyssal systems)
|
||||
@@ -177,6 +177,7 @@ define([
|
||||
descriptionAreaClass: config.descriptionAreaClass,
|
||||
descriptionButtonClass: config.addDescriptionButtonClass,
|
||||
descriptionTextareaClass: config.descriptionTextareaElementClass,
|
||||
summernoteClass: Util.config.summernoteClass,
|
||||
systemNameClass: () => {
|
||||
return (val, render) => {
|
||||
return render(val) === 'A' ? config.fontTriglivianClass : '';
|
||||
@@ -298,7 +299,7 @@ define([
|
||||
},
|
||||
callbacks: {
|
||||
onInit: function(context){
|
||||
// make editable field a big larger
|
||||
// make editable field a bit larger
|
||||
context.editable.css('height', '150px');
|
||||
|
||||
// set default background color
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/console',
|
||||
'conf/system_effect',
|
||||
'conf/signature_type',
|
||||
'bootbox',
|
||||
@@ -18,7 +19,7 @@ define([
|
||||
'bootstrapConfirmation',
|
||||
'bootstrapToggle',
|
||||
'select2'
|
||||
], ($, Init, SystemEffect, SignatureType, bootbox, localforage) => {
|
||||
], ($, Init, Con, SystemEffect, SignatureType, bootbox, localforage) => {
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -83,6 +84,9 @@ define([
|
||||
popoverSmallClass: 'pf-popover-small', // class for small "popover"
|
||||
popoverCharacterClass: 'pf-popover-character', // class for character "popover"
|
||||
|
||||
// Summernote
|
||||
summernoteClass: 'pf-summernote', // class for Summernote "WYSIWYG" elements
|
||||
|
||||
// help
|
||||
helpDefaultClass: 'pf-help-default', // class for "help" tooltip elements
|
||||
helpClass: 'pf-help', // class for "help" tooltip elements
|
||||
@@ -878,9 +882,7 @@ define([
|
||||
/**
|
||||
* show current program version information in browser console
|
||||
*/
|
||||
let showVersionInfo = () => {
|
||||
console.info('PATHFINDER ' + getVersion());
|
||||
};
|
||||
let showVersionInfo = () => Con.showVersionInfo(getVersion());
|
||||
|
||||
/**
|
||||
* polyfill for "passive" events
|
||||
@@ -2771,16 +2773,28 @@ define([
|
||||
return Init.currentSystemData;
|
||||
};
|
||||
|
||||
/**
|
||||
* set current location data
|
||||
* -> system data where current user is located
|
||||
* @param systemId
|
||||
* @param systemName
|
||||
*/
|
||||
let setCurrentLocationData = (systemId, systemName) => {
|
||||
let locationLink = $('#' + config.headCurrentLocationId).find('a');
|
||||
locationLink.data('systemId', systemId);
|
||||
locationLink.data('systemName', systemName);
|
||||
};
|
||||
|
||||
/**
|
||||
* get current location data
|
||||
* -> system data where current user is located
|
||||
* @returns {{id: *, name: *}}
|
||||
*/
|
||||
let getCurrentLocationData = () => {
|
||||
let currentLocationLink = $('#' + config.headCurrentLocationId).find('a');
|
||||
let locationLink = $('#' + config.headCurrentLocationId).find('a');
|
||||
return {
|
||||
id: currentLocationLink.data('systemId'),
|
||||
name: currentLocationLink.data('systemName')
|
||||
id: locationLink.data('systemId') || 0,
|
||||
name: locationLink.data('systemName') || false
|
||||
};
|
||||
};
|
||||
|
||||
@@ -3012,6 +3026,13 @@ define([
|
||||
return Array.from(doc.body.childNodes).some(node => node.nodeType === 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* checks if a given object is a DOM element
|
||||
* @param obj
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let isDomElement = obj => !!(obj && obj.nodeType === 1);
|
||||
|
||||
/**
|
||||
* get deep json object value if exists
|
||||
* -> e.g. key = 'first.last.third' string
|
||||
@@ -3189,6 +3210,7 @@ define([
|
||||
getCurrentCharacterId: getCurrentCharacterId,
|
||||
setCurrentSystemData: setCurrentSystemData,
|
||||
getCurrentSystemData: getCurrentSystemData,
|
||||
setCurrentLocationData: setCurrentLocationData,
|
||||
getCurrentLocationData: getCurrentLocationData,
|
||||
getCurrentUserInfo: getCurrentUserInfo,
|
||||
getCurrentCharacterLog: getCurrentCharacterLog,
|
||||
@@ -3216,6 +3238,7 @@ define([
|
||||
htmlEncode: htmlEncode,
|
||||
htmlDecode: htmlDecode,
|
||||
isValidHtml: isValidHtml,
|
||||
isDomElement: isDomElement,
|
||||
getObjVal: getObjVal,
|
||||
redirect: redirect,
|
||||
logout: logout,
|
||||
|
||||
@@ -227,17 +227,36 @@
|
||||
<h4 class="pf-dynamic-area"><img src="{{ccpImageServer}}/Character/{{id}}_64.jpg"> {{name}} {{{roleLabel}}}</h4>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-8 col-sm-6">
|
||||
<div class="col-xs-12 col-sm-6">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-1 col-sm-11">
|
||||
<div class="checkbox checkbox-primary" title="show/share current location on map">
|
||||
<div class="checkbox checkbox-primary">
|
||||
<input id="logLocation" name="logLocation" value="1" type="checkbox" {{#logLocation}}checked{{/logLocation}}>
|
||||
<label for="logLocation">Auto update current location</label>
|
||||
<label for="logLocation">
|
||||
Auto update current location
|
||||
<i class="fas fa-fw fa-question-circle pf-help-light" title="show/share current location on map"></i>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-sm-6">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<div class="checkbox checkbox-warning" {{^characterAutoLocationSelectEnabled}}title="Globally disabled for all characters"{{/characterAutoLocationSelectEnabled}}>
|
||||
<input id="selectLocation" name="selectLocation" value="1" type="checkbox" {{#selectLocation}}checked{{/selectLocation}} {{^characterAutoLocationSelectEnabled}}disabled{{/characterAutoLocationSelectEnabled}}>
|
||||
<label for="selectLocation">
|
||||
Auto select current location
|
||||
<i class="fas fa-fw fa-question-circle pf-help-light" title="Auto select current system after jump.
|
||||
Unsaved changes (e.g. system description) will be discarded!"
|
||||
></i>
|
||||
<span class="badge bg-color bg-color-grayDarker txt-color txt-color-warning">beta</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6"></div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="character">
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
{{! info text ================================================================================================ }}
|
||||
<div class="col-xs-12 col-sm-9">
|
||||
<div class="pf-dynamic-area {{descriptionAreaClass}}">
|
||||
<div class="{{descriptionTextareaClass}}"></div>
|
||||
<div class="{{descriptionTextareaClass}} {{summernoteClass}}"></div>
|
||||
<i class="fas fa-fw fa-lg fa-pen pull-right {{moduleHeadlineIconClass}} {{descriptionButtonClass}}" data-toggle="tooltip" title="edit description"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -143,6 +143,22 @@
|
||||
@include rotate( -90deg );
|
||||
}
|
||||
|
||||
// rainbow background =============================================================================
|
||||
@keyframes rotateRainbow{
|
||||
0%{
|
||||
background-position-x: 0;
|
||||
}
|
||||
100%{
|
||||
background-position-x: 100vw;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin rainbow(){
|
||||
background: repeating-linear-gradient(-45deg, $green-light 0%, $teal-lighter 12.5%, $teal-lightest 25%, $green 37.5%, $green-light 50%);
|
||||
background-size:100vw 100vw;
|
||||
@include animation(rotateRainbow 3s infinite linear forwards);
|
||||
}
|
||||
|
||||
// navigation link active/hover indicator =========================================================
|
||||
@mixin navigation-active-indicator($position) {
|
||||
content: '';
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
@include background-image(linear-gradient(to right, $green-light, $green-light 100%));
|
||||
|
||||
@include rainbow;
|
||||
|
||||
&.warning{
|
||||
@include background-image(linear-gradient(to right, $brand-warning, $brand-warning 100%));
|
||||
|
||||
@@ -89,7 +89,7 @@ $mapWrapperMaxWidth: $mapWidth + 35px;
|
||||
position: absolute;
|
||||
display: none; // triggered by js
|
||||
z-index: 10000;
|
||||
right: 26px;
|
||||
right: 25px;
|
||||
background: rgba($black, 0.25);
|
||||
@include border-radius(5px);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user