3 Commits

3 changed files with 168 additions and 119 deletions

View File

@@ -208,9 +208,19 @@ export const MapNode: React.FC<MapNodeProps> = ({
<tspan fill={getSecurityColor(security)}>{security.toFixed(1)}</tspan> <tspan fill={getSecurityColor(security)}>{security.toFixed(1)}</tspan>
)} )}
</text> </text>
{/* Dynamic text positioning based on what's shown */}
{(() => {
let currentY = textOffset + 15;
const textElements = [];
// Add signatures if present
if (signatures !== undefined && signatures > 0) {
textElements.push(
<text <text
key="signatures"
x="0" x="0"
y={textOffset + 15} y={currentY}
textAnchor="middle" textAnchor="middle"
fill="#a3a3a3" fill="#a3a3a3"
fontSize="12" fontSize="12"
@@ -222,14 +232,19 @@ export const MapNode: React.FC<MapNodeProps> = ({
transform={`scale(${1 / (1200 / viewBoxWidth)})`} transform={`scale(${1 / (1200 / viewBoxWidth)})`}
transformOrigin="0 0" transformOrigin="0 0"
> >
{signatures !== undefined && signatures > 0 && `📡 ${signatures}`} 📡 {signatures}
</text> </text>
);
currentY += 15;
}
{/* Statistics display - fixed visual size regardless of zoom */} // Add jumps if enabled and present
{showJumps && jumps !== undefined && ( if (showJumps && jumps !== undefined) {
textElements.push(
<text <text
key="jumps"
x="0" x="0"
y={textOffset + 30} y={currentY}
textAnchor="middle" textAnchor="middle"
fill="#60a5fa" fill="#60a5fa"
fontSize="10" fontSize="10"
@@ -243,12 +258,17 @@ export const MapNode: React.FC<MapNodeProps> = ({
> >
🚀 {jumps} 🚀 {jumps}
</text> </text>
)} );
currentY += 15;
}
{showKills && kills !== undefined && ( // Add kills if enabled and present
if (showKills && kills !== undefined) {
textElements.push(
<text <text
key="kills"
x="0" x="0"
y={textOffset + 45} y={currentY}
textAnchor="middle" textAnchor="middle"
fill="#f87171" fill="#f87171"
fontSize="10" fontSize="10"
@@ -262,7 +282,11 @@ export const MapNode: React.FC<MapNodeProps> = ({
> >
{kills} {kills}
</text> </text>
)} );
}
return textElements;
})()}
</g> </g>
); );
} }

View File

@@ -1,4 +1,4 @@
import React, { useState, useRef, useCallback, useEffect } from 'react'; import React, { useState, useRef, useCallback, useEffect, useMemo } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { MapNode } from '@/components/MapNode'; import { MapNode } from '@/components/MapNode';
import { SystemContextMenu } from '@/components/SystemContextMenu'; import { SystemContextMenu } from '@/components/SystemContextMenu';
@@ -11,7 +11,7 @@ import { Header } from './Header';
import { ListCharacters, StartESILogin, SetDestinationForAll, PostRouteForAllByNames, GetCharacterLocations } from 'wailsjs/go/main/App'; import { ListCharacters, StartESILogin, SetDestinationForAll, PostRouteForAllByNames, GetCharacterLocations } from 'wailsjs/go/main/App';
import { toast } from '@/hooks/use-toast'; import { toast } from '@/hooks/use-toast';
import { getSystemsRegions } from '@/utils/systemApi'; import { getSystemsRegions } from '@/utils/systemApi';
import { useSystemJumps, useSystemKills } from '@/hooks/useSystemStatistics'; import { useSystemJumps, useSystemKills, resolveSystemID } from '@/hooks/useSystemStatistics';
import { StatisticsToggle } from './StatisticsToggle'; import { StatisticsToggle } from './StatisticsToggle';
// Interaction/indicator constants // Interaction/indicator constants
@@ -120,9 +120,10 @@ export const RegionMap = ({ regionName, focusSystem, isCompact = false, isWormho
const [showJumps, setShowJumps] = useState(false); const [showJumps, setShowJumps] = useState(false);
const [showKills, setShowKills] = useState(false); const [showKills, setShowKills] = useState(false);
// Cache for system name to ID mappings // System ID cache for statistics lookup
const [systemIDCache, setSystemIDCache] = useState<Map<string, number>>(new Map()); const [systemIDCache, setSystemIDCache] = useState<Map<string, number>>(new Map());
// New: selection/aim state for left-click aimbot behavior // New: selection/aim state for left-click aimbot behavior
const [isSelecting, setIsSelecting] = useState(false); const [isSelecting, setIsSelecting] = useState(false);
const [indicatedSystem, setIndicatedSystem] = useState<string | null>(null); const [indicatedSystem, setIndicatedSystem] = useState<string | null>(null);
@@ -186,13 +187,29 @@ export const RegionMap = ({ regionName, focusSystem, isCompact = false, isWormho
const { data: killsData } = useSystemKills(showKills); const { data: killsData } = useSystemKills(showKills);
useEffect(() => { useEffect(() => {
if (!isLoading && error == null && rsystems && rsystems.size > 0) if (!isLoading && error == null && rsystems && rsystems.size > 0) {
setSystems(rsystems); setSystems(rsystems);
// Pre-resolve all system IDs for statistics lookup
const resolveSystemIDs = async () => {
const newCache = new Map<string, number>();
for (const systemName of rsystems.keys()) {
try {
const id = await resolveSystemID(systemName);
if (id) {
newCache.set(systemName, id);
}
} catch (error) {
console.warn(`Failed to resolve system ID for ${systemName}:`, error);
}
}
setSystemIDCache(newCache);
};
resolveSystemIDs();
}
}, [rsystems, isLoading, error]); }, [rsystems, isLoading, error]);
// For now, we'll use a simplified approach without system ID resolution
// The ESI data will be displayed for systems that have data, but we won't
// be able to match system names to IDs until the binding issue is resolved
useEffect(() => { useEffect(() => {
if (!systems || systems.size === 0) return; if (!systems || systems.size === 0) return;
@@ -519,45 +536,50 @@ export const RegionMap = ({ regionName, focusSystem, isCompact = false, isWormho
return nearestName; return nearestName;
}; };
// Create lookup maps for system statistics
const jumpsBySystemID = useMemo(() => {
if (!jumpsData) return new Map();
const map = new Map<number, number>();
jumpsData.forEach(jump => {
map.set(jump.system_id, jump.ship_jumps);
});
return map;
}, [jumpsData]);
const killsBySystemID = useMemo(() => {
if (!killsData) return new Map();
const map = new Map<number, number>();
killsData.forEach(kill => {
map.set(kill.system_id, kill.ship_kills);
});
return map;
}, [killsData]);
// Helper functions to get statistics for a system // Helper functions to get statistics for a system
const getSystemJumps = (systemName: string): number | undefined => { const getSystemJumps = (systemName: string): number | undefined => {
if (!jumpsData || !showJumps) return undefined; if (!showJumps) return undefined;
// For demonstration, show the first few systems with jump data const systemID = systemIDCache.get(systemName);
// This is a temporary solution until system ID resolution is fixed if (!systemID) return undefined;
const systemNames = Array.from(systems.keys());
const systemIndex = systemNames.indexOf(systemName);
if (systemIndex >= 0 && systemIndex < jumpsData.length) { const jumps = jumpsBySystemID.get(systemID);
const jumps = jumpsData[systemIndex].ship_jumps; if (!jumps || jumps === 0) return undefined;
// Don't show 0 values - return undefined so nothing is rendered
if (jumps === 0) return undefined;
console.log(`🚀 Found ${jumps} jumps for ${systemName} (using index ${systemIndex})`); console.log(`🚀 Found ${jumps} jumps for ${systemName} (ID: ${systemID})`);
return jumps; return jumps;
}
return undefined;
}; };
const getSystemKills = (systemName: string): number | undefined => { const getSystemKills = (systemName: string): number | undefined => {
if (!killsData || !showKills) return undefined; if (!showKills) return undefined;
// For demonstration, show the first few systems with kill data const systemID = systemIDCache.get(systemName);
// This is a temporary solution until system ID resolution is fixed if (!systemID) return undefined;
const systemNames = Array.from(systems.keys());
const systemIndex = systemNames.indexOf(systemName);
if (systemIndex >= 0 && systemIndex < killsData.length) { const kills = killsBySystemID.get(systemID);
const kills = killsData[systemIndex].ship_kills; if (!kills || kills === 0) return undefined;
// Don't show 0 values - return undefined so nothing is rendered
if (kills === 0) return undefined;
console.log(`⚔️ Found ${kills} kills for ${systemName} (using index ${systemIndex})`); console.log(`⚔️ Found ${kills} kills for ${systemName} (ID: ${systemID})`);
return kills; return kills;
}
return undefined;
}; };
// Commit shift selection: toggle all systems within radius // Commit shift selection: toggle all systems within radius
@@ -1200,13 +1222,15 @@ export const RegionMap = ({ regionName, focusSystem, isCompact = false, isWormho
</div> </div>
)} )}
{/* Statistics Toggle */} {/* Statistics Toggle - positioned to avoid overlaps */}
<div className="absolute bottom-4 left-4">
<StatisticsToggle <StatisticsToggle
jumpsEnabled={showJumps} jumpsEnabled={showJumps}
killsEnabled={showKills} killsEnabled={showKills}
onJumpsToggle={setShowJumps} onJumpsToggle={setShowJumps}
onKillsToggle={setShowKills} onKillsToggle={setShowKills}
/> />
</div>
{/* Context Menu */} {/* Context Menu */}
{contextMenu && ( {contextMenu && (

View File

@@ -1,5 +1,4 @@
import React from 'react'; import React from 'react';
import { Switch } from '@/components/ui/switch';
interface StatisticsToggleProps { interface StatisticsToggleProps {
jumpsEnabled: boolean; jumpsEnabled: boolean;
@@ -15,28 +14,30 @@ export const StatisticsToggle: React.FC<StatisticsToggleProps> = ({
onKillsToggle, onKillsToggle,
}) => { }) => {
return ( return (
<div className="absolute top-2 left-2 bg-slate-800/90 backdrop-blur-sm rounded-lg p-3 shadow-lg border border-slate-700"> <div className="bg-slate-800/90 backdrop-blur-sm rounded-lg p-2 shadow-lg border border-slate-700">
<div className="flex flex-col gap-3"> <div className="flex gap-2">
<div className="flex items-center gap-3"> <button
<Switch onClick={() => onJumpsToggle(!jumpsEnabled)}
id="jumps-toggle" className={`p-2 rounded transition-colors ${
checked={jumpsEnabled} jumpsEnabled
onCheckedChange={onJumpsToggle} ? 'bg-blue-600/20 text-blue-400 hover:bg-blue-600/30'
/> : 'bg-gray-600/20 text-gray-400 hover:bg-gray-600/30'
<label htmlFor="jumps-toggle" className="text-sm font-medium text-white"> }`}
🚀 Show Jumps title={jumpsEnabled ? 'Hide Jumps' : 'Show Jumps'}
</label> >
</div> 🚀
<div className="flex items-center gap-3"> </button>
<Switch <button
id="kills-toggle" onClick={() => onKillsToggle(!killsEnabled)}
checked={killsEnabled} className={`p-2 rounded transition-colors ${
onCheckedChange={onKillsToggle} killsEnabled
/> ? 'bg-red-600/20 text-red-400 hover:bg-red-600/30'
<label htmlFor="kills-toggle" className="text-sm font-medium text-white"> : 'bg-gray-600/20 text-gray-400 hover:bg-gray-600/30'
Show Kills }`}
</label> title={killsEnabled ? 'Hide Kills' : 'Show Kills'}
</div> >
</button>
</div> </div>
</div> </div>
); );