- New "Near by" map overlay, closed #481

This commit is contained in:
Exodus4D
2017-04-22 20:46:26 +02:00
parent bc7b7154be
commit 8c93d7731c
16 changed files with 1556 additions and 103 deletions

View File

@@ -413,18 +413,15 @@ class CharacterModel extends BasicModel {
public function updateLog($additionalOptions = []){
$deleteLog = true;
//check if log update is enabled for this user
if( $this->logLocation ){
// Try to pull data from API
if( $accessToken = $this->getAccessToken() ){
$locationData = self::getF3()->ccpClient->getCharacterLocationData($this->_id, $accessToken, $additionalOptions);
if( !empty($locationData['system']['id']) ){
// character is currently in-game
// IDs for "systemId", "stationId and "shipTypeId" that require more data
$lookupIds = [];
@@ -437,13 +434,19 @@ class CharacterModel extends BasicModel {
// get current log data and modify on change
$logData = json_decode(json_encode( $characterLog->getData()), true);
if($logData['system']['id'] !== $locationData['system']['id']){
if(
empty($logData['system']['name']) ||
$logData['system']['id'] !== $locationData['system']['id']
){
// system changed -> request "system name" for current system
$lookupIds[] = $locationData['system']['id'];
}
if( !empty($locationData['station']['id']) ){
if( $logData['station']['id'] !== $locationData['station']['id'] ){
if(
empty($logData['station']['name']) ||
$logData['station']['id'] !== $locationData['station']['id']
){
// station changed -> request "station name" for current station
$lookupIds[] = $locationData['station']['id'];
}
@@ -457,7 +460,10 @@ class CharacterModel extends BasicModel {
$shipData = self::getF3()->ccpClient->getCharacterShipData($this->_id, $accessToken, $additionalOptions);
if( !empty($shipData['ship']['typeId']) ){
if($logData['ship']['typeId'] !== $shipData['ship']['typeId']){
if(
empty($logData['ship']['typeName']) ||
$logData['ship']['typeId'] !== $shipData['ship']['typeId']
){
// ship changed -> request "station name" for current station
$lookupIds[] = $shipData['ship']['typeId'];
}
@@ -471,14 +477,21 @@ class CharacterModel extends BasicModel {
if( !empty($lookupIds) ){
// get "more" information for some Ids (e.g. name)
$universeData = self::getF3()->ccpClient->getUniverseNamesData($lookupIds, $additionalOptions);
$logData = array_replace_recursive($logData, $universeData);
if( !empty($universeData) ){
$deleteLog = false;
$logData = array_replace_recursive($logData, $universeData);
}
}else{
$deleteLog = false;
}
$deleteLog = false;
$characterLog->setData($logData);
$characterLog->save();
if( !$deleteLog ){
$characterLog->setData($logData);
$characterLog->save();
$this->characterLog = $characterLog;
$this->characterLog = $characterLog;
}
}
}
}

View File

@@ -66,6 +66,7 @@ define(['jquery'], function($) {
splashOverlay: 300, // "splash" loading overlay
headerLink: 100, // links in head bar
mapOverlay: 200, // show/hide duration for map overlays
mapOverlayLocal: 180, // show/hide duration for map "local" overlay
mapMoveSystem: 180, // system position has changed animation
mapDeleteSystem: 200, // remove system from map
mapModule: 200, // show/hide of an map module

536
js/app/map/local.js Normal file
View File

@@ -0,0 +1,536 @@
/**
* map overlay functions
* Created by Exodus on 13.04.2017.
*/
define([
'jquery',
'app/init',
'app/util',
'app/map/util'
], function($, Init, Util, MapUtil) {
'use strict';
let config = {
overlayClass: 'pf-map-overlay', // class for all map overlays
overlayLocalClass: 'pf-map-overlay-local', // class for "local" overlay
// left section
overlayLocalContentClass: 'pf-map-overlay-local-content', // class for left area - content
overlayLocalHeadlineClass: 'pf-map-overlay-headline', // class for headline
overlayLocalTableClass: 'pf-local-table', // class for local tables
// right section
overlayLocalTriggerClass: 'pf-map-overlay-local-trigger', // class for open/close trigger icon
overlayLocalOpenClass: 'pf-map-overlay-local-open', // class for open status
overlayLocalMainClass: 'pf-map-overlay-local-main', // class for right area (always visible)
overlayLocalUsersClass: 'pf-map-overlay-local-users', // class for active user count
overlayLocalJumpsClass: 'pf-map-overlay-local-jumps', // class for jump distance for table results
// dataTable
tableImageCellClass: 'pf-table-image-cell', // class for table "image" cells
tableActionCellClass: 'pf-table-action-cell', // class for table "action" cells
tableActionCellIconClass: 'pf-table-action-icon-cell', // class for table "action" icon (icon is part of cell content)
tableCellEllipsisClass: 'pf-table-cell-ellipsis',
tableCellEllipsis80Class: 'pf-table-cell-80',
tableCellEllipsis90Class: 'pf-table-cell-90',
// default "search" radius (jumps) for "near by" pilots
jumps: 3
};
/**
* checks whether overlay is currently open or not
* @param overlay
* @returns {*}
*/
let isOpen = (overlay) => {
return overlay.hasClass(config.overlayLocalOpenClass);
};
/**
* open overlay -> animation
* @param overlay
*/
let openOverlay = (overlay) => {
if( !isOpen(overlay) ){
let overlayMain = overlay.find('.' + config.overlayLocalMainClass);
overlayMain.find('.' + config.overlayLocalTriggerClass).addClass('right');
overlay.addClass(config.overlayLocalOpenClass);
overlay.velocity({
width: '350px'
},{
duration: Init.animationSpeed.mapOverlayLocal,
easing: 'easeOut'
});
}
};
/**
* close overlay -> animation
* @param overlay
*/
let closeOverlay = (overlay) => {
if( isOpen(overlay) ){
let overlayMain = overlay.find('.' + config.overlayLocalMainClass);
overlayMain.find('.' + config.overlayLocalTriggerClass).removeClass('right');
overlay.removeClass(config.overlayLocalOpenClass);
overlay.velocity({
width: '32px'
},{
duration: Init.animationSpeed.mapOverlayLocal,
easing: 'easeOut'
});
}
};
/**
* sets overlay observer
* @param overlay
* @param mapId
*/
let setOverlayObserver = (overlay, mapId) => {
let overlayMain = overlay.find('.' + config.overlayLocalMainClass);
overlayMain.on('click', function(){
let overlayMain = $(this).parent('.' + config.overlayLocalClass);
let isOpenStatus = isOpen(overlayMain);
// store current state in indexDB (client)
MapUtil.storeLocalData('map', mapId, 'showLocal', !isOpenStatus );
// trigger open/close
if( isOpenStatus ){
closeOverlay(overlay);
}else{
openOverlay(overlay);
}
});
overlayMain.initTooltips({
container: 'body',
placement: 'bottom'
});
};
/**
* filter DataTable rows by column data and return rowIds
* @param table
* @param data
* @param values
* @param checkExistence
*/
let filterRows = (table, data = 'id', values = [], checkExistence = true) => {
return table.rows().eq(0).filter( function (rowIdx) {
let rowExists = values.indexOf( table.row(rowIdx ).data()[data] ) !== -1;
if( !checkExistence ){
rowExists = !rowExists;
}
return rowExists;
});
};
/**
* Update the "headline" within the Overlay
* @param overlay
* @param systemData
* @param characterAll
* @param characterLocal
*/
let updateLocaleHeadline = (overlay, systemData, characterAll = 0, characterLocal = 0) => {
let headlineElement = overlay.find('.' + config.overlayLocalHeadlineClass);
let userCountElement = overlay.find('.' + config.overlayLocalUsersClass);
let secClassBase = Util.getSecurityClassForSystem('security');
let secClass = Util.getSecurityClassForSystem(systemData.security);
let childElements = headlineElement.children('span');
childElements.eq(1).removeClass().addClass(
[secClassBase, secClass].join(' ')
).text(systemData.security);
childElements.eq(2).text(systemData.alias ? systemData.alias : systemData.name);
// update userCount for "near by" count -------------------------------------------------------------------
if( characterAll > 0){
userCountElement.toggleClass( 'txt-color-green', true).toggleClass( 'txt-color-red', false);
}else{
userCountElement.toggleClass( 'txt-color-green', false).toggleClass( 'txt-color-red', true);
}
userCountElement.text(characterAll);
// update userCount in current system ---------------------------------------------------------------------
if( characterLocal > 0){
childElements.eq(3).toggleClass( 'txt-color-green', true).toggleClass( 'txt-color-red', false);
}else{
childElements.eq(3).toggleClass( 'txt-color-green', false).toggleClass( 'txt-color-red', true);
}
childElements.eq(3).text(characterLocal);
};
/**
* updates all changed table rows
* @param systemData
* @param userData
*/
$.fn.updateLocalTable = function(systemData, userData){
return this.each(function(){
let overlay = $(this);
let tableElement = overlay.find('.' + config.overlayLocalTableClass);
let localTable = tableElement.DataTable();
let mapId = systemData.mapId;
let characterAllIds = [];
let characterLocalIds = [];
// system is on map (just for security check)
for(let jumps in userData) {
if( userData.hasOwnProperty(jumps) ){
jumps = parseInt(jumps);
for(let j = 0; j < userData[jumps].length; j++){
// add jump distance
userData[jumps][j].jumps = jumps;
let rowData = userData[jumps][j];
// check for existing rows
let indexes = filterRows(localTable, 'id', [rowData.id]);
if(indexes.length > 0){
// row exists -> update
let changedRow = localTable.row( parseInt(indexes[0]) );
let changedRowElement = changedRow.nodes().to$();
// remove tooltips
changedRowElement.find('[title]').tooltip('hide').tooltip('destroy');
// update data
changedRow.data(rowData);
}else{
// new row
localTable.row.add(rowData);
}
if(jumps === 0){
characterLocalIds.push(rowData.id);
}
characterAllIds.push(rowData.id);
}
}
}
// remove rows that no longer exists ----------------------------------------------------------------------
let indexesRemove = filterRows(localTable, 'id', characterAllIds, false);
localTable.rows(indexesRemove).remove();
localTable.draw();
// update system relevant data in overlay -----------------------------------------------------------------
updateLocaleHeadline(overlay, systemData, characterAllIds.length, characterLocalIds.length);
// open Overlay -------------------------------------------------------------------------------------------
if( !isOpen(overlay) ){
let promiseStore = MapUtil.getLocaleData('map', mapId);
promiseStore.then(function(dataStore) {
if(
dataStore &&
dataStore.showLocal
){
openOverlay(overlay);
}
});
}
});
};
/**
* Access a nested JSON object by "dot.notation" syntax
* @param obj
* @param selector
* @returns {*}
*/
let getDescendantProp = (obj, selector) => {
return selector.split('.').reduce(function(a, b) {
return a[b];
}, obj);
};
/**
* init tooltip for a "DataTables" Cell
* @param api
* @param cell
* @param titleSelector
*/
let initCellTooltip = (api, cell, titleSelector = '') => {
$(cell).hover( function(e){
let rowIdx = api.cell(cell).index().row;
let rowData = api.row(rowIdx).data();
$(this).tooltip({
container: 'body',
title: String( getDescendantProp(rowData, titleSelector) ),
placement: 'left',
delay: 100
}).tooltip('show');
}, function(e){
$(this).tooltip('hide');
});
};
/**
* init all map local overlay on a "parent" element
* @returns {*}
*/
$.fn.initLocalOverlay = function(mapId){
return this.each(function(){
let parentElement = $(this);
let overlay = $('<div>', {
class: [config.overlayClass, config.overlayLocalClass].join(' ')
});
let content = $('<div>', {
class: [ 'text-right', config.overlayLocalContentClass].join(' ')
});
// crate new route table
let table = $('<table>', {
class: ['compact', 'order-column', config.overlayLocalTableClass].join(' ')
});
let overlayMain = $('<div>', {
text: '',
class: config.overlayLocalMainClass
}).append(
$('<i>', {
class: ['fa', 'fa-chevron-down', 'fa-fw', 'pf-animate-rotate', config.overlayLocalTriggerClass].join(' ')
}),
$('<span>', {
class: ['badge', 'txt-color', 'txt-color-red', config.overlayLocalUsersClass].join(' '),
text: 0
}),
$('<div>', {
class: config.overlayLocalJumpsClass
}).append(
$('<span>', {
class: ['badge', 'txt-color', 'txt-color-grayLight'].join(' '),
text: config.jumps
}).attr('title', 'jumps')
)
);
let headline = $('<div>', {
class: config.overlayLocalHeadlineClass
}).append(
$('<span>', {
html: 'Near&nbsp;by&nbsp;&nbsp;&nbsp;',
class: 'pull-left'
}),
$('<span>'),
$('<span>'),
$('<span>', {
class: ['badge', ' txt-color', 'txt-color-red'].join(' '),
text: 0
})
);
content.append(headline);
content.append(table);
overlay.append(overlayMain);
overlay.append(content);
// set observer
setOverlayObserver(overlay, mapId);
parentElement.append(overlay);
// init local table ---------------------------------------------------------------------------------------
table.on('draw.dt', function(e, settings){
// init table tooltips
$(this).find('td').initTooltips({
container: 'body',
placement: 'left'
});
// hide pagination in case of only one page
let paginationElement = overlay.find('.dataTables_paginate');
let pageElements = paginationElement.find('span .paginate_button');
if(pageElements.length <= 1){
paginationElement.hide();
}else{
paginationElement.show();
}
});
// table init complete
table.on( 'init.dt', function (){
// init table head tooltips
$(this).initTooltips({
container: 'body',
placement: 'top'
});
});
let localTable = table.DataTable( {
pageLength: 13, // hint: if pagination visible => we need space to show it
paging: true,
lengthChange: false,
ordering: true,
order: [ 0, 'asc' ],
info: false,
searching: false,
hover: false,
autoWidth: false,
rowId: function(rowData) {
return 'pf-local-row_' + rowData.id; // characterId
},
language: {
emptyTable: '<span>You&nbsp;are&nbsp;alone</span>'
},
columnDefs: [
{
targets: 0,
orderable: true,
title: '<span title="jumps" data-toggle="tooltip">&nbsp;</span>',
width: '1px',
className: ['pf-help-default', 'text-center'].join(' '),
data: 'jumps',
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
let api = this.DataTable();
initCellTooltip(api, cell, 'log.system.name');
}
},{
targets: 1,
orderable: false,
title: '',
width: '26px',
className: ['pf-help-default', 'text-center', config.tableImageCellClass].join(' '),
data: 'log.ship',
render: {
_: function(data, type, row, meta){
let value = data.typeName;
if(type === 'display'){
value = '<img src="' + Init.url.ccpImageServer + 'Render/' + data.typeId + '_32.png"/>';
}
return value;
}
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
let api = this.DataTable();
initCellTooltip(api, cell, 'log.ship.typeName');
}
}, {
targets: 2,
orderable: true,
title: 'ship&nbsp;name',
width: '80px',
data: 'log.ship',
render: {
_: function(data, type, row, meta){
let value = data.name;
if(type === 'display'){
value = '<div class="' + config.tableCellEllipsisClass + ' ' + config.tableCellEllipsis80Class + '">' + data.name + '</div>';
}
return value;
},
sort: 'name'
}
},{
targets: 3,
orderable: true,
title: 'pilot',
data: 'name',
render: {
_: function(data, type, row, meta){
let value = data;
if(type === 'display'){
value = '<div class="' + config.tableCellEllipsisClass + ' ' + config.tableCellEllipsis90Class + '">' + data + '</div>';
}
return value;
}
}
},{
targets: 4,
orderable: false,
title: '<i title="docked station" data-toggle="tooltip" class="fa fa-home text-right"></i>',
width: '10px',
className: ['pf-help-default'].join(' '),
data: 'log.station',
render: {
_: function(data, type, row, meta){
let value = '';
if(
type === 'display' &&
data.id
){
value = '<i class="fa fa-home"></i>';
}
return value;
}
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
let api = this.DataTable();
initCellTooltip(api, cell, 'log.station.name');
}
},{
targets: 5,
orderable: false,
title: '<i title="open ingame" data-toggle="tooltip" class="fa fa-id-card text-right"></i>',
width: '10px',
className: [config.tableActionCellClass].join(' '),
data: 'id',
render: {
_: function(data, type, row, meta){
let value = data;
if(type === 'display'){
value = '<i class="fa fa-id-card ' + config.tableActionCellIconClass + '"></i>';
}
return value;
}
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
// open character information window (ingame)
$(cell).on('click', { tableApi: this.DataTable(), cellData: cellData }, function(e){
let cellData = e.data.tableApi.cell(this).data();
Util.openIngameWindow(e.data.cellData);
});
}
}
]
});
});
};
/**
* Clear Overlay and "Reset"
* @param mapId
*/
$.fn.clearLocalTable = function(mapId){
return this.each(function(){
let overlay = $(this);
// update locale overlay headline -------------------------------------------------------------------------
updateLocaleHeadline(overlay, {
name: 'unknown',
security: ''
});
// clear all table rows -----------------------------------------------------------------------------------
let tableElement = overlay.find('.' + config.overlayLocalTableClass);
let localTable = tableElement.DataTable();
localTable.rows().remove().draw();
});
};
});

View File

@@ -15,7 +15,8 @@ define([
'dragToSelect',
'select2',
'app/map/contextmenu',
'app/map/overlay'
'app/map/overlay',
'app/map/local'
], function($, Init, Util, Render, bootbox, MapUtil, System, MagnetizerWrapper) {
'use strict';
@@ -59,13 +60,7 @@ define([
systemDialogSelectClass: 'pf-system-dialog-select', // class for system select Element
// system security classes
systemSec: 'pf-system-sec',
systemSecHigh: 'pf-system-sec-highSec',
systemSecLow: 'pf-system-sec-lowSec',
systemSecNull: 'pf-system-sec-nullSec',
systemSecWHHeigh: 'pf-system-sec-high',
systemSecWHMid: 'pf-system-sec-mid',
systemSecWHLow: 'pf-system-sec-low'
systemSec: 'pf-system-sec'
};
// active jsPlumb instances currently running
@@ -2875,6 +2870,44 @@ define([
mapUpdateQueue.splice(mapQueueIndex, 1);
}
});
// update "local" overlay for this map
mapContainer.on('pf:updateLocal', function(e, userData){
let mapElement = $(this);
let mapOverlay = mapElement.getMapOverlay('local');
let currentCharacterLog = Util.getCurrentCharacterLog();
let currentMapData = Util.getCurrentMapData(userData.config.id);
let clearLocal = true;
if(
currentMapData &&
currentCharacterLog &&
currentCharacterLog.system
){
let currentSystemData = currentMapData.data.systems.filter(function (system) {
return system.systemId === currentCharacterLog.system.id;
});
if(currentSystemData.length){
// current user system is on this map
currentSystemData = currentSystemData[0];
// check for active users "near by" (x jumps radius)
let nearBySystemData = Util.getNearBySystemData(currentSystemData, currentMapData, 3);
let nearByCharacterData = Util.getNearByCharacterData(nearBySystemData, userData.data.systems);
// update "local" table in overlay
mapOverlay.updateLocalTable(currentSystemData, nearByCharacterData);
clearLocal = false;
}
}
if(clearLocal){
mapOverlay.clearLocalTable();
}
});
};
/**
@@ -3009,15 +3042,16 @@ define([
// the current user can only be in a single system ------------------------------------------
if(
characterLogExists &&
!currentUserOnMap &&
currentCharacterLog.system.id === systemId
){
currentUserIsHere = true;
currentUserOnMap = true;
if( !currentUserOnMap ){
currentUserIsHere = true;
currentUserOnMap = true;
// set current location data for header update
headerUpdateData.currentSystemId = $(system).data('id');
headerUpdateData.currentSystemName = currentCharacterLog.system.name;
// set current location data for header update
headerUpdateData.currentSystemId = $(system).data('id');
headerUpdateData.currentSystemName = currentCharacterLog.system.name;
}
}
system.updateSystemUserData(map, tempUserData, currentUserIsHere);
@@ -3291,15 +3325,17 @@ define([
*/
$.fn.initMapScrollbar = function(){
// get Map Scrollbar
let scrollableElement = $(this).find('.' + config.mapWrapperClass);
let mapTabContentElement = $(this);
let scrollableElement = mapTabContentElement.find('.' + config.mapWrapperClass);
let mapElement = mapTabContentElement.find('.' + config.mapClass);
let mapId = mapElement.data('id');
scrollableElement.initCustomScrollbar({
callbacks: {
onScroll: function(){
// scroll complete
let mapElement = $(this).find('.' + config.mapClass);
// store new map scrollOffset -> localDB
MapUtil.storeLocalData('map', mapElement.data('id'), 'offsetX', Math.abs(this.mcs.left) );
MapUtil.storeLocalData('map', mapId, 'offsetX', Math.abs(this.mcs.left) );
},
onScrollStart: function(){
// hide all open xEditable fields
@@ -3310,9 +3346,8 @@ define([
},
whileScrolling:function(){
// update scroll position for drag-frame-selection
let mapElement = $(scrollableElement).find('.' + config.mapClass);
$(mapElement).data('scrollLeft', this.mcs.left);
$(mapElement).data('scrollTop', this.mcs.top);
mapElement.data('scrollLeft', this.mcs.left);
mapElement.data('scrollTop', this.mcs.top);
}
}
});
@@ -3321,6 +3356,8 @@ define([
// add map overlays after scrollbar is initialized
// because of its absolute position
scrollableElement.initMapOverlays();
scrollableElement.initLocalOverlay(mapId);
};
return {

View File

@@ -13,16 +13,13 @@ define([
logTimerCount: 3, // map log timer in seconds
// map
mapClass: 'pf-map', // class for all maps
mapWrapperClass: 'pf-map-wrapper', // wrapper div (scrollable)
// map overlay positions
mapOverlayClass: 'pf-map-overlay', // class for all map overlays
mapOverlayTimerClass: 'pf-map-overlay-timer', // class for map overlay timer e.g. map timer
mapOverlayInfoClass: 'pf-map-overlay-info', // class for map overlay info e.g. map info
// connection overlays
overlayLocalClass: 'pf-map-overlay-local', // class for map overlay "local" table
// system
systemHeadClass: 'pf-system-head', // class for system head
@@ -40,16 +37,6 @@ define([
connectionOverlaySmallClass: 'pf-map-connection-small-overlay' // class for "smaller" overlays
};
/**
* get mapElement from overlay or any child of that
* @param mapOverlay
* @returns {JQuery}
*/
let getMapElementFromOverlay = (mapOverlay) => {
return $(mapOverlay).parents('.' + config.mapWrapperClass).find('.' + config.mapClass);
};
/**
* get MapObject (jsPlumb) from mapElement
* @param mapElement
@@ -66,7 +53,7 @@ define([
* @returns {*}
*/
let getMapObjectFromOverlayIcon = (overlayIcon) => {
let mapElement = getMapElementFromOverlay(overlayIcon);
let mapElement = Util.getMapElementFromOverlay(overlayIcon);
return getMapObjectFromMapElement( mapElement );
};
@@ -381,7 +368,7 @@ define([
iconClass: ['fa', 'fa-fw', 'fa-tags'],
hoverIntent: {
over: function(e){
let mapElement = getMapElementFromOverlay(this);
let mapElement = Util.getMapElementFromOverlay(this);
mapElement.find('.' + config.systemHeadClass).each(function(){
let system = $(this);
// init tooltip if not already exists
@@ -399,7 +386,7 @@ define([
});
},
out: function(e){
let mapElement = getMapElementFromOverlay(this);
let mapElement = Util.getMapElementFromOverlay(this);
mapElement.find('.' + config.systemHeadClass).tooltip('hide');
}
}
@@ -411,7 +398,7 @@ define([
iconClass: ['fa', 'fa-fw', 'fa-link'],
hoverIntent: {
over: function(e){
let mapElement = getMapElementFromOverlay(this);
let mapElement = Util.getMapElementFromOverlay(this);
mapElement.showEndpointOverlays();
},
out: function(e){
@@ -518,7 +505,6 @@ define([
* @returns {*}
*/
$.fn.getMapOverlay = function(overlayType){
let mapWrapperElement = $(this).parents('.' + config.mapWrapperClass);
let mapOverlay = null;
@@ -529,6 +515,9 @@ define([
case 'info':
mapOverlay = mapWrapperElement.find('.' + config.mapOverlayInfoClass);
break;
case 'local':
mapOverlay = mapWrapperElement.find('.' + config.overlayLocalClass);
break;
}
return mapOverlay;
@@ -626,7 +615,7 @@ define([
duration: Init.animationSpeed.mapOverlay,
complete: function(){
counterChart.data('interval', false);
getMapElementFromOverlay(mapOverlayTimer).trigger('pf:unlocked');
Util.getMapElementFromOverlay(mapOverlayTimer).trigger('pf:unlocked');
}
});
}

View File

@@ -201,8 +201,12 @@ define([
let currentMapUserData = Util.getCurrentMapUserData(mapId);
// update map with current user data
if(currentMapUserData){
// trigger "update local" for this map => async
mapElement.trigger('pf:updateLocal', currentMapUserData);
// update map with current user data
mapElement.updateUserData(currentMapUserData);
}
}

View File

@@ -53,6 +53,9 @@ define([
// map module
mapModuleId: 'pf-map-module', // id for main map module
mapTabBarId: 'pf-map-tabs', // id for map tab bar
mapWrapperClass: 'pf-map-wrapper', // wrapper div (scrollable)
mapClass: 'pf-map' , // class for all maps
// animation
animationPulseSuccessClass: 'pf-animation-pulse-success', // animation class
@@ -1270,6 +1273,15 @@ define([
return mapTabElements;
};
/**
* get mapElement from overlay or any child of that
* @param mapOverlay
* @returns {jQuery}
*/
let getMapElementFromOverlay = (mapOverlay) => {
return $(mapOverlay).parents('.' + config.mapWrapperClass).find('.' + config.mapClass);
};
/**
* get the map module object or create a new module
* @returns {*|HTMLElement}
@@ -1802,6 +1814,98 @@ define([
return userInfo;
};
/**
* get "nearBy" systemData based on a jump radius around a currentSystem
* @param currentSystemData
* @param currentMapData
* @param jumps
* @param foundSystemIds
* @returns {{systemData: *, tree: {}}}
*/
let getNearBySystemData = (currentSystemData, currentMapData, jumps, foundSystemIds = []) => {
// look for systemData by ID
let getSystemData = (systemId) => {
for(let j = 0; j < currentMapData.data.systems.length; j++){
let systemData = currentMapData.data.systems[j];
if(systemData.id === systemId){
return systemData;
}
}
return false;
};
// skip systems that are already found in recursive calls
foundSystemIds.push(currentSystemData.id);
let nearBySystems = {
systemData: currentSystemData,
tree: {}
};
jumps--;
if(jumps > 0){
for(let i = 0; i < currentMapData.data.connections.length; i++){
let connectionData = currentMapData.data.connections[i];
let type = ''; // "source" OR "target"
if(connectionData.source === currentSystemData.id){
type = 'target';
}else if(connectionData.target === currentSystemData.id){
type = 'source';
}
if(
type &&
foundSystemIds.indexOf(connectionData[type]) === -1
){
let newSystemData = getSystemData(connectionData[type]);
if(newSystemData){
nearBySystems.tree[connectionData[type]] = getNearBySystemData(newSystemData, currentMapData, jumps, foundSystemIds);
}
}
}
}
return nearBySystems;
};
/**
* get current character data from all characters who are "near by" the current user
* -> see getNearBySystemData()
* @param nearBySystems
* @param userData
* @param jumps
* @param data
* @returns {{}}
*/
let getNearByCharacterData = (nearBySystems, userData, jumps = 0, data = {}) => {
let getCharacterDataBySystemId = (systemId) => {
for(let i = 0; i < userData.length; i++){
if(userData[i].id === systemId){
return userData[i].user;
}
}
return [];
};
let characterData = getCharacterDataBySystemId(nearBySystems.systemData.systemId);
if(characterData.length){
data[jumps] = data[jumps] ? data[jumps] : [];
data[jumps] = [...data[jumps], ...characterData];
}
jumps++;
for(let prop in nearBySystems.tree) {
if( nearBySystems.tree.hasOwnProperty(prop) ){
let tmpSystemData = nearBySystems.tree[prop];
data = getNearByCharacterData(tmpSystemData, userData, jumps, data);
}
}
return data;
};
/**
* set new destination for a system
* -> CREST request
@@ -2064,6 +2168,7 @@ define([
setSyncStatus: setSyncStatus,
getSyncType: getSyncType,
isXHRAborted: isXHRAborted,
getMapElementFromOverlay: getMapElementFromOverlay,
getMapModule: getMapModule,
getSystemEffectData: getSystemEffectData,
getSystemEffectTable: getSystemEffectTable,
@@ -2091,6 +2196,8 @@ define([
getCurrentUserInfo: getCurrentUserInfo,
getCurrentCharacterLog: getCurrentCharacterLog,
flattenXEditableSelectArray: flattenXEditableSelectArray,
getNearBySystemData: getNearBySystemData,
getNearByCharacterData: getNearByCharacterData,
setDestination: setDestination,
convertDateToString: convertDateToString,
getOpenDialogs: getOpenDialogs,

File diff suppressed because one or more lines are too long

View File

@@ -66,6 +66,7 @@ define(['jquery'], function($) {
splashOverlay: 300, // "splash" loading overlay
headerLink: 100, // links in head bar
mapOverlay: 200, // show/hide duration for map overlays
mapOverlayLocal: 180, // show/hide duration for map "local" overlay
mapMoveSystem: 180, // system position has changed animation
mapDeleteSystem: 200, // remove system from map
mapModule: 200, // show/hide of an map module

View File

@@ -0,0 +1,536 @@
/**
* map overlay functions
* Created by Exodus on 13.04.2017.
*/
define([
'jquery',
'app/init',
'app/util',
'app/map/util'
], function($, Init, Util, MapUtil) {
'use strict';
let config = {
overlayClass: 'pf-map-overlay', // class for all map overlays
overlayLocalClass: 'pf-map-overlay-local', // class for "local" overlay
// left section
overlayLocalContentClass: 'pf-map-overlay-local-content', // class for left area - content
overlayLocalHeadlineClass: 'pf-map-overlay-headline', // class for headline
overlayLocalTableClass: 'pf-local-table', // class for local tables
// right section
overlayLocalTriggerClass: 'pf-map-overlay-local-trigger', // class for open/close trigger icon
overlayLocalOpenClass: 'pf-map-overlay-local-open', // class for open status
overlayLocalMainClass: 'pf-map-overlay-local-main', // class for right area (always visible)
overlayLocalUsersClass: 'pf-map-overlay-local-users', // class for active user count
overlayLocalJumpsClass: 'pf-map-overlay-local-jumps', // class for jump distance for table results
// dataTable
tableImageCellClass: 'pf-table-image-cell', // class for table "image" cells
tableActionCellClass: 'pf-table-action-cell', // class for table "action" cells
tableActionCellIconClass: 'pf-table-action-icon-cell', // class for table "action" icon (icon is part of cell content)
tableCellEllipsisClass: 'pf-table-cell-ellipsis',
tableCellEllipsis80Class: 'pf-table-cell-80',
tableCellEllipsis90Class: 'pf-table-cell-90',
// default "search" radius (jumps) for "near by" pilots
jumps: 3
};
/**
* checks whether overlay is currently open or not
* @param overlay
* @returns {*}
*/
let isOpen = (overlay) => {
return overlay.hasClass(config.overlayLocalOpenClass);
};
/**
* open overlay -> animation
* @param overlay
*/
let openOverlay = (overlay) => {
if( !isOpen(overlay) ){
let overlayMain = overlay.find('.' + config.overlayLocalMainClass);
overlayMain.find('.' + config.overlayLocalTriggerClass).addClass('right');
overlay.addClass(config.overlayLocalOpenClass);
overlay.velocity({
width: '350px'
},{
duration: Init.animationSpeed.mapOverlayLocal,
easing: 'easeOut'
});
}
};
/**
* close overlay -> animation
* @param overlay
*/
let closeOverlay = (overlay) => {
if( isOpen(overlay) ){
let overlayMain = overlay.find('.' + config.overlayLocalMainClass);
overlayMain.find('.' + config.overlayLocalTriggerClass).removeClass('right');
overlay.removeClass(config.overlayLocalOpenClass);
overlay.velocity({
width: '32px'
},{
duration: Init.animationSpeed.mapOverlayLocal,
easing: 'easeOut'
});
}
};
/**
* sets overlay observer
* @param overlay
* @param mapId
*/
let setOverlayObserver = (overlay, mapId) => {
let overlayMain = overlay.find('.' + config.overlayLocalMainClass);
overlayMain.on('click', function(){
let overlayMain = $(this).parent('.' + config.overlayLocalClass);
let isOpenStatus = isOpen(overlayMain);
// store current state in indexDB (client)
MapUtil.storeLocalData('map', mapId, 'showLocal', !isOpenStatus );
// trigger open/close
if( isOpenStatus ){
closeOverlay(overlay);
}else{
openOverlay(overlay);
}
});
overlayMain.initTooltips({
container: 'body',
placement: 'bottom'
});
};
/**
* filter DataTable rows by column data and return rowIds
* @param table
* @param data
* @param values
* @param checkExistence
*/
let filterRows = (table, data = 'id', values = [], checkExistence = true) => {
return table.rows().eq(0).filter( function (rowIdx) {
let rowExists = values.indexOf( table.row(rowIdx ).data()[data] ) !== -1;
if( !checkExistence ){
rowExists = !rowExists;
}
return rowExists;
});
};
/**
* Update the "headline" within the Overlay
* @param overlay
* @param systemData
* @param characterAll
* @param characterLocal
*/
let updateLocaleHeadline = (overlay, systemData, characterAll = 0, characterLocal = 0) => {
let headlineElement = overlay.find('.' + config.overlayLocalHeadlineClass);
let userCountElement = overlay.find('.' + config.overlayLocalUsersClass);
let secClassBase = Util.getSecurityClassForSystem('security');
let secClass = Util.getSecurityClassForSystem(systemData.security);
let childElements = headlineElement.children('span');
childElements.eq(1).removeClass().addClass(
[secClassBase, secClass].join(' ')
).text(systemData.security);
childElements.eq(2).text(systemData.alias ? systemData.alias : systemData.name);
// update userCount for "near by" count -------------------------------------------------------------------
if( characterAll > 0){
userCountElement.toggleClass( 'txt-color-green', true).toggleClass( 'txt-color-red', false);
}else{
userCountElement.toggleClass( 'txt-color-green', false).toggleClass( 'txt-color-red', true);
}
userCountElement.text(characterAll);
// update userCount in current system ---------------------------------------------------------------------
if( characterLocal > 0){
childElements.eq(3).toggleClass( 'txt-color-green', true).toggleClass( 'txt-color-red', false);
}else{
childElements.eq(3).toggleClass( 'txt-color-green', false).toggleClass( 'txt-color-red', true);
}
childElements.eq(3).text(characterLocal);
};
/**
* updates all changed table rows
* @param systemData
* @param userData
*/
$.fn.updateLocalTable = function(systemData, userData){
return this.each(function(){
let overlay = $(this);
let tableElement = overlay.find('.' + config.overlayLocalTableClass);
let localTable = tableElement.DataTable();
let mapId = systemData.mapId;
let characterAllIds = [];
let characterLocalIds = [];
// system is on map (just for security check)
for(let jumps in userData) {
if( userData.hasOwnProperty(jumps) ){
jumps = parseInt(jumps);
for(let j = 0; j < userData[jumps].length; j++){
// add jump distance
userData[jumps][j].jumps = jumps;
let rowData = userData[jumps][j];
// check for existing rows
let indexes = filterRows(localTable, 'id', [rowData.id]);
if(indexes.length > 0){
// row exists -> update
let changedRow = localTable.row( parseInt(indexes[0]) );
let changedRowElement = changedRow.nodes().to$();
// remove tooltips
changedRowElement.find('[title]').tooltip('hide').tooltip('destroy');
// update data
changedRow.data(rowData);
}else{
// new row
localTable.row.add(rowData);
}
if(jumps === 0){
characterLocalIds.push(rowData.id);
}
characterAllIds.push(rowData.id);
}
}
}
// remove rows that no longer exists ----------------------------------------------------------------------
let indexesRemove = filterRows(localTable, 'id', characterAllIds, false);
localTable.rows(indexesRemove).remove();
localTable.draw();
// update system relevant data in overlay -----------------------------------------------------------------
updateLocaleHeadline(overlay, systemData, characterAllIds.length, characterLocalIds.length);
// open Overlay -------------------------------------------------------------------------------------------
if( !isOpen(overlay) ){
let promiseStore = MapUtil.getLocaleData('map', mapId);
promiseStore.then(function(dataStore) {
if(
dataStore &&
dataStore.showLocal
){
openOverlay(overlay);
}
});
}
});
};
/**
* Access a nested JSON object by "dot.notation" syntax
* @param obj
* @param selector
* @returns {*}
*/
let getDescendantProp = (obj, selector) => {
return selector.split('.').reduce(function(a, b) {
return a[b];
}, obj);
};
/**
* init tooltip for a "DataTables" Cell
* @param api
* @param cell
* @param titleSelector
*/
let initCellTooltip = (api, cell, titleSelector = '') => {
$(cell).hover( function(e){
let rowIdx = api.cell(cell).index().row;
let rowData = api.row(rowIdx).data();
$(this).tooltip({
container: 'body',
title: String( getDescendantProp(rowData, titleSelector) ),
placement: 'left',
delay: 100
}).tooltip('show');
}, function(e){
$(this).tooltip('hide');
});
};
/**
* init all map local overlay on a "parent" element
* @returns {*}
*/
$.fn.initLocalOverlay = function(mapId){
return this.each(function(){
let parentElement = $(this);
let overlay = $('<div>', {
class: [config.overlayClass, config.overlayLocalClass].join(' ')
});
let content = $('<div>', {
class: [ 'text-right', config.overlayLocalContentClass].join(' ')
});
// crate new route table
let table = $('<table>', {
class: ['compact', 'order-column', config.overlayLocalTableClass].join(' ')
});
let overlayMain = $('<div>', {
text: '',
class: config.overlayLocalMainClass
}).append(
$('<i>', {
class: ['fa', 'fa-chevron-down', 'fa-fw', 'pf-animate-rotate', config.overlayLocalTriggerClass].join(' ')
}),
$('<span>', {
class: ['badge', 'txt-color', 'txt-color-red', config.overlayLocalUsersClass].join(' '),
text: 0
}),
$('<div>', {
class: config.overlayLocalJumpsClass
}).append(
$('<span>', {
class: ['badge', 'txt-color', 'txt-color-grayLight'].join(' '),
text: config.jumps
}).attr('title', 'jumps')
)
);
let headline = $('<div>', {
class: config.overlayLocalHeadlineClass
}).append(
$('<span>', {
html: 'Near&nbsp;by&nbsp;&nbsp;&nbsp;',
class: 'pull-left'
}),
$('<span>'),
$('<span>'),
$('<span>', {
class: ['badge', ' txt-color', 'txt-color-red'].join(' '),
text: 0
})
);
content.append(headline);
content.append(table);
overlay.append(overlayMain);
overlay.append(content);
// set observer
setOverlayObserver(overlay, mapId);
parentElement.append(overlay);
// init local table ---------------------------------------------------------------------------------------
table.on('draw.dt', function(e, settings){
// init table tooltips
$(this).find('td').initTooltips({
container: 'body',
placement: 'left'
});
// hide pagination in case of only one page
let paginationElement = overlay.find('.dataTables_paginate');
let pageElements = paginationElement.find('span .paginate_button');
if(pageElements.length <= 1){
paginationElement.hide();
}else{
paginationElement.show();
}
});
// table init complete
table.on( 'init.dt', function (){
// init table head tooltips
$(this).initTooltips({
container: 'body',
placement: 'top'
});
});
let localTable = table.DataTable( {
pageLength: 13, // hint: if pagination visible => we need space to show it
paging: true,
lengthChange: false,
ordering: true,
order: [ 0, 'asc' ],
info: false,
searching: false,
hover: false,
autoWidth: false,
rowId: function(rowData) {
return 'pf-local-row_' + rowData.id; // characterId
},
language: {
emptyTable: '<span>You&nbsp;are&nbsp;alone</span>'
},
columnDefs: [
{
targets: 0,
orderable: true,
title: '<span title="jumps" data-toggle="tooltip">&nbsp;</span>',
width: '1px',
className: ['pf-help-default', 'text-center'].join(' '),
data: 'jumps',
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
let api = this.DataTable();
initCellTooltip(api, cell, 'log.system.name');
}
},{
targets: 1,
orderable: false,
title: '',
width: '26px',
className: ['pf-help-default', 'text-center', config.tableImageCellClass].join(' '),
data: 'log.ship',
render: {
_: function(data, type, row, meta){
let value = data.typeName;
if(type === 'display'){
value = '<img src="' + Init.url.ccpImageServer + 'Render/' + data.typeId + '_32.png"/>';
}
return value;
}
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
let api = this.DataTable();
initCellTooltip(api, cell, 'log.ship.typeName');
}
}, {
targets: 2,
orderable: true,
title: 'ship&nbsp;name',
width: '80px',
data: 'log.ship',
render: {
_: function(data, type, row, meta){
let value = data.name;
if(type === 'display'){
value = '<div class="' + config.tableCellEllipsisClass + ' ' + config.tableCellEllipsis80Class + '">' + data.name + '</div>';
}
return value;
},
sort: 'name'
}
},{
targets: 3,
orderable: true,
title: 'pilot',
data: 'name',
render: {
_: function(data, type, row, meta){
let value = data;
if(type === 'display'){
value = '<div class="' + config.tableCellEllipsisClass + ' ' + config.tableCellEllipsis90Class + '">' + data + '</div>';
}
return value;
}
}
},{
targets: 4,
orderable: false,
title: '<i title="docked station" data-toggle="tooltip" class="fa fa-home text-right"></i>',
width: '10px',
className: ['pf-help-default'].join(' '),
data: 'log.station',
render: {
_: function(data, type, row, meta){
let value = '';
if(
type === 'display' &&
data.id
){
value = '<i class="fa fa-home"></i>';
}
return value;
}
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
let api = this.DataTable();
initCellTooltip(api, cell, 'log.station.name');
}
},{
targets: 5,
orderable: false,
title: '<i title="open ingame" data-toggle="tooltip" class="fa fa-id-card text-right"></i>',
width: '10px',
className: [config.tableActionCellClass].join(' '),
data: 'id',
render: {
_: function(data, type, row, meta){
let value = data;
if(type === 'display'){
value = '<i class="fa fa-id-card ' + config.tableActionCellIconClass + '"></i>';
}
return value;
}
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
// open character information window (ingame)
$(cell).on('click', { tableApi: this.DataTable(), cellData: cellData }, function(e){
let cellData = e.data.tableApi.cell(this).data();
Util.openIngameWindow(e.data.cellData);
});
}
}
]
});
});
};
/**
* Clear Overlay and "Reset"
* @param mapId
*/
$.fn.clearLocalTable = function(mapId){
return this.each(function(){
let overlay = $(this);
// update locale overlay headline -------------------------------------------------------------------------
updateLocaleHeadline(overlay, {
name: 'unknown',
security: ''
});
// clear all table rows -----------------------------------------------------------------------------------
let tableElement = overlay.find('.' + config.overlayLocalTableClass);
let localTable = tableElement.DataTable();
localTable.rows().remove().draw();
});
};
});

View File

@@ -15,7 +15,8 @@ define([
'dragToSelect',
'select2',
'app/map/contextmenu',
'app/map/overlay'
'app/map/overlay',
'app/map/local'
], function($, Init, Util, Render, bootbox, MapUtil, System, MagnetizerWrapper) {
'use strict';
@@ -59,13 +60,7 @@ define([
systemDialogSelectClass: 'pf-system-dialog-select', // class for system select Element
// system security classes
systemSec: 'pf-system-sec',
systemSecHigh: 'pf-system-sec-highSec',
systemSecLow: 'pf-system-sec-lowSec',
systemSecNull: 'pf-system-sec-nullSec',
systemSecWHHeigh: 'pf-system-sec-high',
systemSecWHMid: 'pf-system-sec-mid',
systemSecWHLow: 'pf-system-sec-low'
systemSec: 'pf-system-sec'
};
// active jsPlumb instances currently running
@@ -2875,6 +2870,44 @@ define([
mapUpdateQueue.splice(mapQueueIndex, 1);
}
});
// update "local" overlay for this map
mapContainer.on('pf:updateLocal', function(e, userData){
let mapElement = $(this);
let mapOverlay = mapElement.getMapOverlay('local');
let currentCharacterLog = Util.getCurrentCharacterLog();
let currentMapData = Util.getCurrentMapData(userData.config.id);
let clearLocal = true;
if(
currentMapData &&
currentCharacterLog &&
currentCharacterLog.system
){
let currentSystemData = currentMapData.data.systems.filter(function (system) {
return system.systemId === currentCharacterLog.system.id;
});
if(currentSystemData.length){
// current user system is on this map
currentSystemData = currentSystemData[0];
// check for active users "near by" (x jumps radius)
let nearBySystemData = Util.getNearBySystemData(currentSystemData, currentMapData, 3);
let nearByCharacterData = Util.getNearByCharacterData(nearBySystemData, userData.data.systems);
// update "local" table in overlay
mapOverlay.updateLocalTable(currentSystemData, nearByCharacterData);
clearLocal = false;
}
}
if(clearLocal){
mapOverlay.clearLocalTable();
}
});
};
/**
@@ -3009,15 +3042,16 @@ define([
// the current user can only be in a single system ------------------------------------------
if(
characterLogExists &&
!currentUserOnMap &&
currentCharacterLog.system.id === systemId
){
currentUserIsHere = true;
currentUserOnMap = true;
if( !currentUserOnMap ){
currentUserIsHere = true;
currentUserOnMap = true;
// set current location data for header update
headerUpdateData.currentSystemId = $(system).data('id');
headerUpdateData.currentSystemName = currentCharacterLog.system.name;
// set current location data for header update
headerUpdateData.currentSystemId = $(system).data('id');
headerUpdateData.currentSystemName = currentCharacterLog.system.name;
}
}
system.updateSystemUserData(map, tempUserData, currentUserIsHere);
@@ -3291,15 +3325,17 @@ define([
*/
$.fn.initMapScrollbar = function(){
// get Map Scrollbar
let scrollableElement = $(this).find('.' + config.mapWrapperClass);
let mapTabContentElement = $(this);
let scrollableElement = mapTabContentElement.find('.' + config.mapWrapperClass);
let mapElement = mapTabContentElement.find('.' + config.mapClass);
let mapId = mapElement.data('id');
scrollableElement.initCustomScrollbar({
callbacks: {
onScroll: function(){
// scroll complete
let mapElement = $(this).find('.' + config.mapClass);
// store new map scrollOffset -> localDB
MapUtil.storeLocalData('map', mapElement.data('id'), 'offsetX', Math.abs(this.mcs.left) );
MapUtil.storeLocalData('map', mapId, 'offsetX', Math.abs(this.mcs.left) );
},
onScrollStart: function(){
// hide all open xEditable fields
@@ -3310,9 +3346,8 @@ define([
},
whileScrolling:function(){
// update scroll position for drag-frame-selection
let mapElement = $(scrollableElement).find('.' + config.mapClass);
$(mapElement).data('scrollLeft', this.mcs.left);
$(mapElement).data('scrollTop', this.mcs.top);
mapElement.data('scrollLeft', this.mcs.left);
mapElement.data('scrollTop', this.mcs.top);
}
}
});
@@ -3321,6 +3356,8 @@ define([
// add map overlays after scrollbar is initialized
// because of its absolute position
scrollableElement.initMapOverlays();
scrollableElement.initLocalOverlay(mapId);
};
return {

View File

@@ -13,16 +13,13 @@ define([
logTimerCount: 3, // map log timer in seconds
// map
mapClass: 'pf-map', // class for all maps
mapWrapperClass: 'pf-map-wrapper', // wrapper div (scrollable)
// map overlay positions
mapOverlayClass: 'pf-map-overlay', // class for all map overlays
mapOverlayTimerClass: 'pf-map-overlay-timer', // class for map overlay timer e.g. map timer
mapOverlayInfoClass: 'pf-map-overlay-info', // class for map overlay info e.g. map info
// connection overlays
overlayLocalClass: 'pf-map-overlay-local', // class for map overlay "local" table
// system
systemHeadClass: 'pf-system-head', // class for system head
@@ -40,16 +37,6 @@ define([
connectionOverlaySmallClass: 'pf-map-connection-small-overlay' // class for "smaller" overlays
};
/**
* get mapElement from overlay or any child of that
* @param mapOverlay
* @returns {JQuery}
*/
let getMapElementFromOverlay = (mapOverlay) => {
return $(mapOverlay).parents('.' + config.mapWrapperClass).find('.' + config.mapClass);
};
/**
* get MapObject (jsPlumb) from mapElement
* @param mapElement
@@ -66,7 +53,7 @@ define([
* @returns {*}
*/
let getMapObjectFromOverlayIcon = (overlayIcon) => {
let mapElement = getMapElementFromOverlay(overlayIcon);
let mapElement = Util.getMapElementFromOverlay(overlayIcon);
return getMapObjectFromMapElement( mapElement );
};
@@ -381,7 +368,7 @@ define([
iconClass: ['fa', 'fa-fw', 'fa-tags'],
hoverIntent: {
over: function(e){
let mapElement = getMapElementFromOverlay(this);
let mapElement = Util.getMapElementFromOverlay(this);
mapElement.find('.' + config.systemHeadClass).each(function(){
let system = $(this);
// init tooltip if not already exists
@@ -399,7 +386,7 @@ define([
});
},
out: function(e){
let mapElement = getMapElementFromOverlay(this);
let mapElement = Util.getMapElementFromOverlay(this);
mapElement.find('.' + config.systemHeadClass).tooltip('hide');
}
}
@@ -411,7 +398,7 @@ define([
iconClass: ['fa', 'fa-fw', 'fa-link'],
hoverIntent: {
over: function(e){
let mapElement = getMapElementFromOverlay(this);
let mapElement = Util.getMapElementFromOverlay(this);
mapElement.showEndpointOverlays();
},
out: function(e){
@@ -518,7 +505,6 @@ define([
* @returns {*}
*/
$.fn.getMapOverlay = function(overlayType){
let mapWrapperElement = $(this).parents('.' + config.mapWrapperClass);
let mapOverlay = null;
@@ -529,6 +515,9 @@ define([
case 'info':
mapOverlay = mapWrapperElement.find('.' + config.mapOverlayInfoClass);
break;
case 'local':
mapOverlay = mapWrapperElement.find('.' + config.overlayLocalClass);
break;
}
return mapOverlay;
@@ -626,7 +615,7 @@ define([
duration: Init.animationSpeed.mapOverlay,
complete: function(){
counterChart.data('interval', false);
getMapElementFromOverlay(mapOverlayTimer).trigger('pf:unlocked');
Util.getMapElementFromOverlay(mapOverlayTimer).trigger('pf:unlocked');
}
});
}

View File

@@ -201,8 +201,12 @@ define([
let currentMapUserData = Util.getCurrentMapUserData(mapId);
// update map with current user data
if(currentMapUserData){
// trigger "update local" for this map => async
mapElement.trigger('pf:updateLocal', currentMapUserData);
// update map with current user data
mapElement.updateUserData(currentMapUserData);
}
}

View File

@@ -53,6 +53,9 @@ define([
// map module
mapModuleId: 'pf-map-module', // id for main map module
mapTabBarId: 'pf-map-tabs', // id for map tab bar
mapWrapperClass: 'pf-map-wrapper', // wrapper div (scrollable)
mapClass: 'pf-map' , // class for all maps
// animation
animationPulseSuccessClass: 'pf-animation-pulse-success', // animation class
@@ -1270,6 +1273,15 @@ define([
return mapTabElements;
};
/**
* get mapElement from overlay or any child of that
* @param mapOverlay
* @returns {jQuery}
*/
let getMapElementFromOverlay = (mapOverlay) => {
return $(mapOverlay).parents('.' + config.mapWrapperClass).find('.' + config.mapClass);
};
/**
* get the map module object or create a new module
* @returns {*|HTMLElement}
@@ -1802,6 +1814,98 @@ define([
return userInfo;
};
/**
* get "nearBy" systemData based on a jump radius around a currentSystem
* @param currentSystemData
* @param currentMapData
* @param jumps
* @param foundSystemIds
* @returns {{systemData: *, tree: {}}}
*/
let getNearBySystemData = (currentSystemData, currentMapData, jumps, foundSystemIds = []) => {
// look for systemData by ID
let getSystemData = (systemId) => {
for(let j = 0; j < currentMapData.data.systems.length; j++){
let systemData = currentMapData.data.systems[j];
if(systemData.id === systemId){
return systemData;
}
}
return false;
};
// skip systems that are already found in recursive calls
foundSystemIds.push(currentSystemData.id);
let nearBySystems = {
systemData: currentSystemData,
tree: {}
};
jumps--;
if(jumps > 0){
for(let i = 0; i < currentMapData.data.connections.length; i++){
let connectionData = currentMapData.data.connections[i];
let type = ''; // "source" OR "target"
if(connectionData.source === currentSystemData.id){
type = 'target';
}else if(connectionData.target === currentSystemData.id){
type = 'source';
}
if(
type &&
foundSystemIds.indexOf(connectionData[type]) === -1
){
let newSystemData = getSystemData(connectionData[type]);
if(newSystemData){
nearBySystems.tree[connectionData[type]] = getNearBySystemData(newSystemData, currentMapData, jumps, foundSystemIds);
}
}
}
}
return nearBySystems;
};
/**
* get current character data from all characters who are "near by" the current user
* -> see getNearBySystemData()
* @param nearBySystems
* @param userData
* @param jumps
* @param data
* @returns {{}}
*/
let getNearByCharacterData = (nearBySystems, userData, jumps = 0, data = {}) => {
let getCharacterDataBySystemId = (systemId) => {
for(let i = 0; i < userData.length; i++){
if(userData[i].id === systemId){
return userData[i].user;
}
}
return [];
};
let characterData = getCharacterDataBySystemId(nearBySystems.systemData.systemId);
if(characterData.length){
data[jumps] = data[jumps] ? data[jumps] : [];
data[jumps] = [...data[jumps], ...characterData];
}
jumps++;
for(let prop in nearBySystems.tree) {
if( nearBySystems.tree.hasOwnProperty(prop) ){
let tmpSystemData = nearBySystems.tree[prop];
data = getNearByCharacterData(tmpSystemData, userData, jumps, data);
}
}
return data;
};
/**
* set new destination for a system
* -> CREST request
@@ -2064,6 +2168,7 @@ define([
setSyncStatus: setSyncStatus,
getSyncType: getSyncType,
isXHRAborted: isXHRAborted,
getMapElementFromOverlay: getMapElementFromOverlay,
getMapModule: getMapModule,
getSystemEffectData: getSystemEffectData,
getSystemEffectTable: getSystemEffectTable,
@@ -2091,6 +2196,8 @@ define([
getCurrentUserInfo: getCurrentUserInfo,
getCurrentCharacterLog: getCurrentCharacterLog,
flattenXEditableSelectArray: flattenXEditableSelectArray,
getNearBySystemData: getNearBySystemData,
getNearByCharacterData: getNearByCharacterData,
setDestination: setDestination,
convertDateToString: convertDateToString,
getOpenDialogs: getOpenDialogs,

View File

@@ -69,23 +69,24 @@ $mapWidth: 2500px ;
position: absolute;
display: none; // triggered by js
z-index: 10000;
height: 36px;
right: 10px;
background: rgba($black, 0.25);
@include border-radius(5px);
&.pf-map-overlay-timer{
width: 36px;
bottom: 23px;
width: 36px;
height: 36px;
}
&.pf-map-overlay-info{
top: 8px;
height: 36px;
min-height: 36px;
min-width: 36px;
color: $gray-darker;
padding: 3px;
line-height: 26px;
min-height: 36px;
min-width: 36px;
i{
margin: 0; // overwrite default
@@ -115,6 +116,93 @@ $mapWidth: 2500px ;
}
}
}
&.pf-map-overlay-local{
top: 54px;
min-height: 80px;
width: 32px;
display: block;
will-change: width;
.pf-map-overlay-local-content {
margin-right: 36px;
padding: 5px 0 5px 5px;
overflow: hidden;
.pf-map-overlay-headline{
font-size: 12px;
font-family: $font-family-bold;
white-space: nowrap;
.badge{
margin-left: 5px;
}
.pf-system-sec{
cursor: default; // overwrite
}
}
.pf-local-table {
font-size: 10px;
td {
white-space: nowrap;
.pf-table-cell-ellipsis{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.pf-table-cell-80{
width: 90px; // 100 + padding for "order" icons
}
.pf-table-cell-90{
width: 100px; // 100 + padding for "order" icons
}
}
}
.dataTables_paginate,
.dataTables_empty{
white-space: nowrap;
}
}
.pf-map-overlay-local-main{
position: absolute;
top: 0;
right: 0;
height: 100%;
padding: 3px;
width: 32px;
cursor: pointer;
text-align: center;
border-left: 1px solid $gray-darker;
.pf-map-overlay-local-trigger{
margin-bottom: 10px;
}
i{
font-size: 12px;
}
}
.pf-map-overlay-local-jumps{
position: absolute;
bottom: 5px;
width: calc(100% - 6px);
}
.badge{
font-family: Arial, sans-serif; // fix for element width on custom font family
background-color: $gray-darker;
}
}
}
// 20x20px grid background

View File

@@ -117,7 +117,7 @@ table.dataTable.order-column tbody tr > .sorting_2,
table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,
table.dataTable.display tbody tr > .sorting_2,
table.dataTable.display tbody tr > .sorting_3 {
background-color: #fafafa;
background-color: $gray-darker;
}
table.dataTable.order-column tbody tr.selected > .sorting_1,
table.dataTable.order-column tbody tr.selected > .sorting_2,
@@ -186,9 +186,13 @@ table.dataTable.no-footer {
table.dataTable.nowrap th, table.dataTable.nowrap td {
white-space: nowrap;
}
table.dataTable.compact thead th:not(.sorting_disabled),
table.dataTable.compact thead td:not(.sorting_disabled) {
padding: 4px 17px 4px 4px;
}
table.dataTable.compact thead th,
table.dataTable.compact thead td {
padding: 4px 17px 4px 4px;
padding: 4px 4px 4px 4px;
}
table.dataTable.compact tfoot th,
table.dataTable.compact tfoot td {