diff --git a/js/app/map/map.js b/js/app/map/map.js index 07178811..070738d7 100644 --- a/js/app/map/map.js +++ b/js/app/map/map.js @@ -35,6 +35,7 @@ define([ systemLockedClass: 'pf-system-locked', // class for locked systems on a map systemHeadClass: 'pf-system-head', // class for system head systemHeadNameClass: 'pf-system-head-name', // class for system name + systemHeadCounterClass: 'pf-system-head-counter', // class for system user counter systemHeadExpandClass: 'pf-system-head-expand', // class for system head expand arrow systemHeadInfoClass: 'pf-system-head-info', // class for system info systemBodyClass: 'pf-system-body', // class for system body @@ -125,16 +126,21 @@ define([ * @param map * @param data * @param currentUserIsHere boolean - if the current user is in this system + * @param options */ - $.fn.updateSystemUserData = function(map, data, currentUserIsHere){ + $.fn.updateSystemUserData = function(map, data, currentUserIsHere, options){ let system = $(this); let systemId = system.attr('id'); + let compactView = Util.getObjVal(options, 'compactView'); + + // find countElement -> minimizedUI + let systemCount = system.find('.' + config.systemHeadCounterClass); // find system body - let systemBody = $( system.find('.' + config.systemBodyClass) ); + let systemBody = system.find('.' + config.systemBodyClass); // find expand arrow - let systemHeadExpand = $( system.find('.' + config.systemHeadExpandClass) ); + let systemHeadExpand = system.find('.' + config.systemHeadExpandClass); let oldCacheKey = system.data('userCache'); let oldUserCount = system.data('userCount'); @@ -154,6 +160,11 @@ define([ data.user ){ let cacheArray = []; + + // we need to add "view mode" option to key + // -> if view mode change detected -> key no longer valid + cacheArray.push(compactView ? 'compact' : 'default'); + // loop all active pilots and build cache-key for(let i = 0; i < data.user.length; i++){ userCounter++; @@ -171,71 +182,73 @@ define([ // remove all content systemBody.empty(); - // loop "again" and build DOM object with user information - for(let j = 0; j < data.user.length; j++){ - let userData = data.user[j]; + if(compactView){ + // compact system layout-> pilot count shown in systemHead + systemCount.text(userCounter); - let statusClass = Util.getStatusInfoForCharacter(userData, 'class'); - let userName = userData.name; + system.toggleSystemTooltip('destroy', {}); + systemHeadExpand.hide(); + system.toggleBody(false, map, {}); - let item = $('
', { - class: config.systemBodyItemClass - }).append( - $('', { - text: userData.log.ship.typeName, - class: config.systemBodyRightClass - }) - ).append( - $('', { - class: ['fas', 'fa-circle', config.systemBodyItemStatusClass, statusClass].join(' ') - }) - ).append( - $('', { - class: config.systemBodyItemNameClass, - text: userName - }) - ); + map.revalidate(systemId); + }else{ + systemCount.empty(); - systemBody.append(item); - } + // show active pilots in body + pilots count tooltip + // loop "again" and build DOM object with user information + for(let j = 0; j < data.user.length; j++){ + let userData = data.user[j]; + let statusClass = Util.getStatusInfoForCharacter(userData, 'class'); + let userName = userData.name; - // ==================================================================================================== + let item = $('
', { + class: config.systemBodyItemClass + }).append( + $('', { + text: userData.log.ship.typeName, + class: config.systemBodyRightClass + }) + ).append( + $('', { + class: ['fas', 'fa-circle', config.systemBodyItemStatusClass, statusClass].join(' ') + }) + ).append( + $('', { + class: config.systemBodyItemNameClass, + text: userName + }) + ); - // user count changed -> change tooltip content + systemBody.append(item); + } - // set tooltip color - let highlight = ''; - if(userCounter > oldUserCount){ - highlight = 'good'; - }else if(userCounter < oldUserCount){ - highlight = 'bad'; - } + // user count changed -> change tooltip content + let highlight = ''; + if(userCounter >= oldUserCount){ + highlight = 'good'; + }else if(userCounter < oldUserCount){ + highlight = 'bad'; + } - let tooltipOptions = { - systemId: systemId, - highlight: highlight, - userCount: userCounter - }; + let tooltipOptions = { + systemId: systemId, + highlight: highlight, + userCount: userCounter + }; - // show system head - systemHeadExpand.velocity('stop', true).velocity({ - width: '10px' - },{ - duration: 50, - display: 'inline-block', - progress: function(){ - //re-validate element size and repaint - map.revalidate( systemId ); - }, - complete: function(){ - // show system body - system.toggleBody(true, map, {complete: function(system){ + // show system head + systemHeadExpand.css('display', 'inline-block'); + + // show system body + system.toggleBody(true, map, { + complete: function(system){ // show active user tooltip system.toggleSystemTooltip('show', tooltipOptions); - }}); - } - }); + map.revalidate( systemId ); + } + }); + } } }else{ // no user data found for this system @@ -247,16 +260,13 @@ define([ oldCacheKey && oldCacheKey.length > 0 ){ - // remove tooltip + // reset all elements + systemCount.empty(); system.toggleSystemTooltip('destroy', {}); + systemHeadExpand.hide(); + system.toggleBody(false, map, {}); - // no user -> clear SystemBody - systemHeadExpand.velocity('stop').velocity('reverse',{ - display: 'none', - complete: function(){ - system.toggleBody(false, map, {}); - } - }); + map.revalidate(systemId); } } }; @@ -305,7 +315,7 @@ define([ begin: function(){ }, progress: function(){ - // revalidate element size and repaint + // re-validate element size and repaint map.revalidate( systemDomId ); }, complete: function(){ @@ -389,6 +399,10 @@ define([ $('', { class: systemHeadClasses.join(' '), }).attr('data-value', systemName), + // System users count + $('', { + class: [config.systemHeadCounterClass, Util.config.popoverTriggerClass].join(' ') + }), // System locked status $('', { class: ['fas', 'fa-lock', 'fa-fw'].join(' ') @@ -2717,8 +2731,8 @@ define([ width: newWidth, 'min-width': minWidth + 'px' },{ - easing: 'easeInOutQuart', - duration: 120, + easing: 'easeOut', + duration: 60, progress: function(){ // repaint connections of current system map.revalidate(systemId); @@ -2761,6 +2775,27 @@ define([ selector: '.' + config.systemClass + ' .' + config.systemHeadExpandClass }); + // system "active users" popover ------------------------------------------------------------------------------ + mapContainer.hoverIntent({ + over: function(e){ + let counterElement = $(this); + let systemElement = counterElement.closest('.' + config.systemClass); + let mapId = systemElement.data('mapid'); + let systemId = systemElement.data('systemId'); + let userData = Util.getCurrentMapUserData(mapId); + let systemUserData = Util.getCharacterDataBySystemId(userData.data.systems, systemId); + + counterElement.addSystemPilotTooltip(systemUserData, { + trigger: 'manual', + placement: 'right' + }).setPopoverSmall().popover('show'); + }, + out: function(e){ + $(this).destroyPopover(); + }, + selector: '.' + config.systemHeadCounterClass + }); + // system "effect" popover ------------------------------------------------------------------------------------ // -> event delegation to system elements, popup only if needed (hover) mapContainer.hoverIntent({ @@ -3010,18 +3045,20 @@ define([ // container must exist! otherwise systems can not be updated if(mapElement !== undefined){ - mapElement = $(mapElement); - // get current character log data - let characterLogExists = false; - let currentCharacterLog = Util.getCurrentCharacterLog(); - // 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, @@ -3089,7 +3126,7 @@ define([ } } - system.updateSystemUserData(map, tempUserData, currentUserIsHere); + system.updateSystemUserData(map, tempUserData, currentUserIsHere, {compactView: compactView}); } // users who are not in any map system -------------------------------------------------------------------- @@ -3329,6 +3366,12 @@ define([ option: 'mapEndpoint', toggle: false }); + + // init compact system UI -------------------------------------------------------------------------- + mapContainer.triggerMenuEvent('MapOption', { + option: 'mapCompact', + toggle: false + }); }; // show nice visualization effect --------------------------------------------------------------------- diff --git a/js/app/map/overlay.js b/js/app/map/overlay.js index 99d167f1..7a7be63b 100644 --- a/js/app/map/overlay.js +++ b/js/app/map/overlay.js @@ -360,6 +360,12 @@ define([ } } }, + mapCompact: { + title: 'compact layout', + trigger: 'active', + class: 'pf-map-overlay-compact', + iconClass: ['fas', 'fa-fw', 'fa-compress'] + }, connection: { title: 'WH data', trigger: 'hover', diff --git a/js/app/map/util.js b/js/app/map/util.js index 61dce3a2..c4098429 100644 --- a/js/app/map/util.js +++ b/js/app/map/util.js @@ -21,6 +21,7 @@ define([ mapClass: 'pf-map', // class for all maps mapGridClass: 'pf-grid-small', // class for map grid snapping + mapCompactClass: 'pf-compact', // class for map compact system UI systemIdPrefix: 'pf-system-', // id prefix for a system systemClass: 'pf-system', // class for all systems @@ -53,6 +54,11 @@ define([ description: 'Endpoint overlay', onEnable: 'showEndpointOverlays', // jQuery extension function onDisable: 'hideEndpointOverlays' // jQuery extension function + }, + mapCompact : { + buttonId: Util.config.menuButtonCompactId, + description: 'Compact system layout', + class: 'mapCompactClass' } }; @@ -1105,10 +1111,40 @@ define([ }); }; + /** + * add system pilot tooltip + * @param systemUserData + * @param options + * @returns {*} + */ + $.fn.addSystemPilotTooltip = function(systemUserData, options){ + let content = Util.getSystemPilotsTable(systemUserData); + + let defaultOptions = { + placement: 'top', + html: true, + trigger: 'hover', + container: 'body', + title: 'Pilots', + content: content, + delay: { + show: 150, + hide: 0 + }, + }; + + options = $.extend({}, defaultOptions, options); + + return this.each(function(){ + $(this).popover(options); + }); + }; + /** * add system effect tooltip * @param security * @param effect + * @param options * @returns {*} */ $.fn.addSystemEffectTooltip = function(security, effect, options){ diff --git a/js/app/page.js b/js/app/page.js index 70316d3f..5b7bc4d2 100644 --- a/js/app/page.js +++ b/js/app/page.js @@ -345,7 +345,7 @@ define([ $('', { class: 'list-group-item', id: Util.config.menuButtonGridId - }).html('   Grid snapping').prepend( + }).html('  Grid snapping').prepend( $('',{ class: 'fas fa-th fa-fw' }) @@ -359,7 +359,7 @@ define([ $('', { class: 'list-group-item', id: Util.config.menuButtonMagnetizerId - }).html('   Magnetizing').prepend( + }).html('  Magnetizing').prepend( $('',{ class: 'fas fa-magnet fa-fw' }) @@ -373,7 +373,7 @@ define([ $('', { class: 'list-group-item', id: Util.config.menuButtonEndpointId - }).html('   Signatures').prepend( + }).html('  Signatures').prepend( $('',{ class: 'fas fa-link fa-fw' }) @@ -383,6 +383,25 @@ define([ toggle: true }); }) + ).append( + $('', { + class: 'list-group-item', + id: Util.config.menuButtonCompactId + }).html('  Compact').prepend( + $('',{ + class: 'fas fa-compress fa-fw' + }) + ).append( + $('',{ + class: 'badge bg-color bg-color-gray txt-color txt-color-warning', + text: 'beta' + }) + ).on('click', function(){ + Util.getMapModule().getActiveMap().triggerMenuEvent('MapOption', { + option: 'mapCompact', + toggle: true + }); + }) ).append( getMenuHeadline('Help') ).append( diff --git a/js/app/util.js b/js/app/util.js index 0af29bf1..f6cfc318 100644 --- a/js/app/util.js +++ b/js/app/util.js @@ -41,6 +41,7 @@ define([ menuButtonMagnetizerId: 'pf-menu-button-magnetizer', // id for menu button "magnetizer" menuButtonGridId: 'pf-menu-button-grid', // id for menu button "grid snap" menuButtonEndpointId: 'pf-menu-button-endpoint', // id for menu button "endpoint" overlays + menuButtonCompactId: 'pf-menu-button-compact', // id for menu button "compact" UI map view menuButtonMapDeleteId: 'pf-menu-button-map-delete', // id for menu button "delete map" settingsMessageVelocityOptions: { @@ -56,6 +57,9 @@ define([ mapWrapperClass: 'pf-map-wrapper', // wrapper div (scrollable) mapClass: 'pf-map' , // class for all maps + // util + userStatusClass: 'pf-user-status', // class for player status + // select2 select2Class: 'pf-select2', // class for all "Select2" elements @@ -960,6 +964,21 @@ define([ }); }; + /** + * get hash from string + * @returns {number} + */ + String.prototype.hashCode = function() { + let hash = 0, i, chr; + if (this.length === 0) return hash; + for (i = 0; i < this.length; i++) { + chr = this.charCodeAt(i); + hash = ((hash << 5) - hash) + chr; + hash |= 0; // Convert to 32bit integer + } + return hash; + }; + initPassiveEvents(); }; @@ -1707,6 +1726,51 @@ define([ return table; }; + /** + * get a HTML table with pilots/ship names + * @param users + * @returns {string} + */ + let getSystemPilotsTable = users => { + let table = ''; + if(users.length > 0){ + + let getRow = (statusClass, userName, shipName, shipTypeName, mass) => { + let row = ''; + row += ''; + row += statusClass !== null ? '' : ''; + row += ''; + row += ''; + row += userName; + row += ''; + row += ''; + row += shipName; + row += ''; + row += ''; + row += shipTypeName; + row += ''; + row += ''; + row += mass; + row += ''; + row += ''; + return row; + }; + + let massAll = 0; + table += ''; + for(let user of users){ + massAll += parseInt(user.log.ship.mass); + let statusClass = getStatusInfoForCharacter(user, 'class'); + let mass = formatMassValue(user.log.ship.mass); + table += getRow(statusClass, user.name, user.log.ship.name, user.log.ship.typeName, mass); + } + table += getRow(null, '', '', '', formatMassValue(massAll)); + table += '
'; + } + + return table; + }; + /** * get a HTML table with information for multiple systems * e.g. for popover @@ -2174,6 +2238,23 @@ define([ return nearBySystems; }; + /** + * get userData (pilots) from systemId + * @param userData + * @param systemId + * @returns {*} + */ + let getCharacterDataBySystemId = (userData, systemId) => { + if(userData && userData.length){ + for(let i = 0; i < userData.length; i++){ + if(userData[i].id === systemId){ + return userData[i].user; + } + } + } + return []; + }; + /** * get current character data from all characters who are "nearby" the current user * -> see getNearBySystemData() @@ -2185,20 +2266,11 @@ define([ */ 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 filterFinalCharData = function(tmpFinalCharData){ return this.id !== tmpFinalCharData.id; }; - let characterData = getCharacterDataBySystemId(nearBySystems.systemData.systemId); + let characterData = getCharacterDataBySystemId(userData, nearBySystems.systemData.systemId); if(characterData.length){ // filter (remove) characterData for "already" added chars @@ -2659,6 +2731,7 @@ define([ getSystemEffectData: getSystemEffectData, getSystemEffectTable: getSystemEffectTable, getSystemPlanetsTable: getSystemPlanetsTable, + getSystemPilotsTable: getSystemPilotsTable, getSystemsInfoTable: getSystemsInfoTable, getStatusInfoForCharacter: getStatusInfoForCharacter, getSecurityClassForSystem: getSecurityClassForSystem, @@ -2685,6 +2758,7 @@ define([ getCurrentUserInfo: getCurrentUserInfo, getCurrentCharacterLog: getCurrentCharacterLog, flattenXEditableSelectArray: flattenXEditableSelectArray, + getCharacterDataBySystemId: getCharacterDataBySystemId, getNearBySystemData: getNearBySystemData, getNearByCharacterData: getNearByCharacterData, setDestination: setDestination, diff --git a/public/templates/view/login.html b/public/templates/view/login.html index 6e3fe695..bc60b155 100644 --- a/public/templates/view/login.html +++ b/public/templates/view/login.html @@ -161,7 +161,7 @@
-
+
Account settings @@ -172,7 +172,7 @@ Task-Manager
-
+

Pathfinder

  • SSL encrypted connection
  • @@ -217,9 +217,9 @@
-
+
-
+
Map selection @@ -231,7 +231,7 @@
-
+

Map module

  • Live synchronisation between clients
  • @@ -296,12 +296,11 @@
-
-
+
System description @@ -310,7 +309,7 @@
-
+

System module

  • Quick access to all relevant information
  • @@ -338,9 +337,9 @@
-
+
-
+
Signature table @@ -349,7 +348,7 @@
-
+

Signature module

  • Share system signature information
  • @@ -375,11 +374,10 @@
-
-
+
Killboard diagram @@ -388,7 +386,7 @@
-
+

Killboard module

-
+
-
+
Routes @@ -421,7 +419,7 @@
-
+

Route module

  • Search for routes between systems
  • @@ -455,18 +453,56 @@
-
+
+ + Jump mass log + +
-
+
+

Mass Log

+
    +
  • Track ship jump mass for wormholes
  • +
  • Compare multiple connections by mass left
  • +
  • Pre-calculate your current ship mass before jumping
  • +
+
+ +
+ +
+ + Intel structures + +
+ +
+

Intel module  new

+
    +
  • Share player owned structure data
  • +
  • Add/Update multiple structures from D-scan: ctrl + c
  • +
  • +
      +
    • Map owner information to structures
    • +
    • Add custom notes to structures
    • +
    • Mark structures 'online', 'offline'
    • +
    +
  • +
+
+
+ +
+ -
+

System statistics module

  • Live in-game system data
  • @@ -480,15 +516,15 @@
-
+
-
+ -
+

User statistics

  • User activity logging
  • @@ -507,35 +543,16 @@
-
- -
- - Jump mass log - -
- -
-

Mass Log   new

-
    -
  • Track ship jump mass for wormholes
  • -
  • Compare multiple connections by mass left
  • -
  • Pre-calculate your current ship mass before jumping
  • -
-
- -
- -
+ -
+

Logging

  • Separate *.log files per map
  • @@ -549,18 +566,16 @@
-
+
-
- -
+ -
-

Discord/Slack integration  new

+
+

Discord/Slack integration

  • Send "rally point" push notifications
  • @@ -576,11 +591,6 @@
- -
- - -
-
+ -
+

Member administration

  • Manage your corporation members
  • @@ -724,15 +734,15 @@
-
+
-
+ -
+

Map settings

  • Manage global corporation map settings
  • @@ -773,13 +783,13 @@
-
+ -
+

Requirements check

  • Checks your server type/status
  • @@ -793,15 +803,15 @@
-
+
-
+ -
+

Database setup

  • Check DB connections
  • diff --git a/sass/_variables.scss b/sass/_variables.scss index 4a0dcf47..79636093 100644 --- a/sass/_variables.scss +++ b/sass/_variables.scss @@ -314,7 +314,7 @@ $container-tablet: ((720px + $grid-gutter-width)); $container-sm: $container-tablet; // Medium screen / desktop -$container-desktop: ((1040px + $grid-gutter-width)); +$container-desktop: ((1060px + $grid-gutter-width)); //** For `$screen-md-min` and up. $container-md: $container-desktop; diff --git a/sass/layout/_landing.scss b/sass/layout/_landing.scss index d7159753..6ebc019c 100644 --- a/sass/layout/_landing.scss +++ b/sass/layout/_landing.scss @@ -115,25 +115,28 @@ a[data-gallery] { position: relative; + display: inline-block; + overflow: hidden; // hide initial overlapping "before" element" + margin: 5px 0 15px 0; + box-shadow: 0 4px 10px rgba(0,0,0,0.4); &:before{ - content: '\f002'; + content: '\f06e'; font-family: 'Font Awesome 5 Free'; font-size: 20px; - font-weight: bold; - line-height: 20px; color: $orange; position: absolute; - top: 9px; height: 100%; width: 100%; - padding-top: calc(50% - 10px); z-index: 10; - text-align: center; @include transition(transform 0.1s ease-out, opacity 0.1s ease-out); will-change: transform, opacity; transform: scale(1.3,1.3); opacity: 0; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; } &:hover{ @@ -143,7 +146,7 @@ } &:before{ - @include transition-delay( 0.1s ); + @include transition-delay( 0.05s ); transform: scale(1,1); opacity: 1; } @@ -155,12 +158,10 @@ style: solid; color: $gray-darkest } - margin: 5px 0 15px 0; display: inline-block; will-change: all; @include filter(brightness( 100% )); @include transition(all 0.2s ease-out); - @include box-shadow(0 4px 10px rgba(0,0,0, 0.4)); &.pf-landing-image-preview-small{ diff --git a/sass/layout/_map.scss b/sass/layout/_map.scss index 2be0a6e1..7e3cdf1a 100644 --- a/sass/layout/_map.scss +++ b/sass/layout/_map.scss @@ -327,6 +327,19 @@ $mapWrapperMaxWidth: $mapWidth + 35px; margin-right: 2px; } + .pf-system-head-counter{ + display: inline-block; + text-align: right; + min-width: 8px; + margin-right: 1px; + color: $green; + cursor: help; + + &:empty{ + display: none; + } + } + .pf-system-effect{ font-size: 11px; } @@ -339,6 +352,7 @@ $mapWrapperMaxWidth: $mapWidth + 35px; .pf-system-head-expand{ margin-left: 2px; color: $gray-light; + width: 10px; display: none; // triggered by JS }