feat(Map): Add highlighting for imperial space systems depends on faction

Fixes #11
This commit is contained in:
achichenkov
2024-09-29 17:57:07 +03:00
parent 501840086b
commit 4c0ad0dd66
12 changed files with 185 additions and 10 deletions

View File

@@ -1,4 +1,4 @@
import React, { ForwardedRef, forwardRef, MouseEvent, useCallback } from 'react'; import { ForwardedRef, forwardRef, MouseEvent, useCallback, useEffect } from 'react';
import ReactFlow, { import ReactFlow, {
Background, Background,
ConnectionMode, ConnectionMode,
@@ -94,6 +94,7 @@ interface MapCompProps {
minimapClasses?: string; minimapClasses?: string;
isShowMinimap?: boolean; isShowMinimap?: boolean;
onSystemContextMenu: (event: MouseEvent<Element>, systemId: string) => void; onSystemContextMenu: (event: MouseEvent<Element>, systemId: string) => void;
showKSpaceBG?: boolean;
} }
const MapComp = ({ const MapComp = ({
@@ -105,6 +106,7 @@ const MapComp = ({
onConnectionInfoClick, onConnectionInfoClick,
onSelectionContextMenu, onSelectionContextMenu,
isShowMinimap, isShowMinimap,
showKSpaceBG,
}: MapCompProps) => { }: MapCompProps) => {
const [nodes, , onNodesChange] = useNodesState<SolarSystemRawType>(initialNodes); const [nodes, , onNodesChange] = useNodesState<SolarSystemRawType>(initialNodes);
const [edges, , onEdgesChange] = useEdgesState<Edge<SolarSystemConnection>[]>(initialEdges); const [edges, , onEdgesChange] = useEdgesState<Edge<SolarSystemConnection>[]>(initialEdges);
@@ -169,6 +171,13 @@ const MapComp = ({
localStorage.setItem(SESSION_KEY.viewPort, JSON.stringify(viewport)); localStorage.setItem(SESSION_KEY.viewPort, JSON.stringify(viewport));
}; };
useEffect(() => {
update(x => ({
...x,
showKSpaceBG: showKSpaceBG,
}));
}, [showKSpaceBG, update]);
return ( return (
<> <>
<div className={classes.MapRoot}> <div className={classes.MapRoot}>

View File

@@ -7,6 +7,7 @@ export type MapData = MapUnionTypes & {
isConnecting: boolean; isConnecting: boolean;
hoverNodeId: string | null; hoverNodeId: string | null;
visibleNodes: Set<string>; visibleNodes: Set<string>;
showKSpaceBG: boolean;
}; };
interface MapProviderProps { interface MapProviderProps {
@@ -27,6 +28,7 @@ const INITIAL_DATA: MapData = {
connections: [], connections: [],
hoverNodeId: null, hoverNodeId: null,
visibleNodes: new Set(), visibleNodes: new Set(),
showKSpaceBG: false,
}; };
export interface MapContextProps { export interface MapContextProps {
@@ -38,6 +40,7 @@ export interface MapContextProps {
const MapContext = createContext<MapContextProps>({ const MapContext = createContext<MapContextProps>({
update: () => {}, update: () => {},
data: { ...INITIAL_DATA }, data: { ...INITIAL_DATA },
// @ts-ignore
outCommand: async () => void 0, outCommand: async () => void 0,
}); });

View File

@@ -23,6 +23,62 @@ $tooltip-bg: #202020; // Темный фон для подсказок
border-radius: 5px; border-radius: 5px;
position: relative; position: relative;
z-index: 1; z-index: 1;
overflow: hidden;
&.Mataria, &.Amarria, &.Gallente, &.Caldaria {
&::Before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-size: cover;
background-position: 50% 50%;
z-index: -1;
background-repeat: no-repeat;
border-radius: 3px;
}
}
&.Mataria {
&::before {
background-image: url("/images/mataria.png");
opacity: 0.6;
background-position-x: -28px;
background-position-y: -3px;
}
}
&.Caldaria {
&::before {
background-image: url("/images/caldaria.png");
opacity: 0.6;
background-position-x: -16px;
background-position-y: -17px;
}
}
&.Amarria {
&::before {
opacity: 0.45;
background-image: url("/images/amarr.png");
background-position-x: 0px;
background-position-y: -1px;
width: calc(100% + 10px)
}
}
&.Gallente {
&::before {
opacity: 0.6;
background-image: url("/images/gallente.png");
background-position-x: -1px;
background-position-y: -10px;
}
}
&.selected { &.selected {
border-color: $pastel-pink; border-color: $pastel-pink;

View File

@@ -19,6 +19,14 @@ import { PrimeIcons } from 'primereact/api';
import { LabelsManager } from '@/hooks/Mapper/utils/labelsManager.ts'; import { LabelsManager } from '@/hooks/Mapper/utils/labelsManager.ts';
import { OutCommand } from '@/hooks/Mapper/types'; import { OutCommand } from '@/hooks/Mapper/types';
import { useDoubleClick } from '@/hooks/Mapper/hooks/useDoubleClick.ts'; import { useDoubleClick } from '@/hooks/Mapper/hooks/useDoubleClick.ts';
import { REGIONS_MAP, Spaces } from '@/hooks/Mapper/constants';
const SpaceToClass: Record<string, string> = {
[Spaces.Caldari]: classes.Caldaria,
[Spaces.Matar]: classes.Mataria,
[Spaces.Amarr]: classes.Amarria,
[Spaces.Gallente]: classes.Gallente,
};
const sortedLabels = (labels: string[]) => { const sortedLabels = (labels: string[]) => {
if (labels === null) { if (labels === null) {
@@ -50,6 +58,7 @@ export const SolarSystemNode = memo(({ data, selected }: WrapNodeProps<MapSolarS
statics, statics,
effect_name, effect_name,
region_name, region_name,
region_id,
is_shattered, is_shattered,
solar_system_name, solar_system_name,
} = data.system_static_info; } = data.system_static_info;
@@ -69,6 +78,7 @@ export const SolarSystemNode = memo(({ data, selected }: WrapNodeProps<MapSolarS
isConnecting, isConnecting,
hoverNodeId, hoverNodeId,
visibleNodes, visibleNodes,
showKSpaceBG,
}, },
outCommand, outCommand,
} = useMapState(); } = useMapState();
@@ -114,6 +124,9 @@ export const SolarSystemNode = memo(({ data, selected }: WrapNodeProps<MapSolarS
const showHandlers = isConnecting || hoverNodeId === id; const showHandlers = isConnecting || hoverNodeId === id;
const space = showKSpaceBG ? REGIONS_MAP[region_id] : '';
const regionClass = showKSpaceBG ? SpaceToClass[space] : null;
return ( return (
<> <>
{visible && ( {visible && (
@@ -147,7 +160,11 @@ export const SolarSystemNode = memo(({ data, selected }: WrapNodeProps<MapSolarS
</div> </div>
)} )}
<div className={clsx(classes.RootCustomNode, classes[STATUS_CLASSES[status]], { [classes.selected]: selected })}> <div
className={clsx(classes.RootCustomNode, regionClass, classes[STATUS_CLASSES[status]], {
[classes.selected]: selected,
})}
>
{visible && ( {visible && (
<> <>
<div className={classes.HeadRow}> <div className={classes.HeadRow}>
@@ -183,7 +200,13 @@ export const SolarSystemNode = memo(({ data, selected }: WrapNodeProps<MapSolarS
)} )}
{!isWormhole && !customName && ( {!isWormhole && !customName && (
<div className="text-stone-400 whitespace-nowrap overflow-hidden text-ellipsis mr-0.5"> <div
className={clsx('text-stone-400 whitespace-nowrap overflow-hidden text-ellipsis mr-0.5', {
['text-teal-100 font-bold']: space === Spaces.Caldari,
['text-yellow-100 font-bold']: space === Spaces.Amarr || space === Spaces.Matar,
['text-lime-200/80 font-bold']: space === Spaces.Gallente,
})}
>
{region_name} {region_name}
</div> </div>
)} )}

View File

@@ -13,6 +13,8 @@ interface RightBarProps {
export const RightBar = ({ onShowOnTheMap }: RightBarProps) => { export const RightBar = ({ onShowOnTheMap }: RightBarProps) => {
const { outCommand, interfaceSettings, setInterfaceSettings } = useMapRootState(); const { outCommand, interfaceSettings, setInterfaceSettings } = useMapRootState();
const isShowMinimap = interfaceSettings.isShowMinimap === undefined ? true : interfaceSettings.isShowMinimap;
const handleAddCharacter = useCallback(() => { const handleAddCharacter = useCallback(() => {
outCommand({ outCommand({
type: OutCommand.addCharacter, type: OutCommand.addCharacter,
@@ -27,6 +29,13 @@ export const RightBar = ({ onShowOnTheMap }: RightBarProps) => {
})); }));
}, [setInterfaceSettings]); }, [setInterfaceSettings]);
const toggleKSpace = useCallback(() => {
setInterfaceSettings(x => ({
...x,
isShowKSpace: !x.isShowKSpace,
}));
}, [setInterfaceSettings]);
const toggleMenu = useCallback(() => { const toggleMenu = useCallback(() => {
setInterfaceSettings(x => ({ setInterfaceSettings(x => ({
...x, ...x,
@@ -67,19 +76,31 @@ export const RightBar = ({ onShowOnTheMap }: RightBarProps) => {
<div className="flex flex-col items-center mb-2 gap-1"> <div className="flex flex-col items-center mb-2 gap-1">
<WdTooltipWrapper <WdTooltipWrapper
content={interfaceSettings.isShowMinimap ? 'Hide minimap' : 'Show minimap'} content={
interfaceSettings.isShowKSpace ? 'Hide highlighting Imperial Space' : 'Show highlighting Imperial Space'
}
position={TooltipPosition.left} position={TooltipPosition.left}
> >
<button
className="btn bg-transparent text-gray-400 hover:text-white border-transparent hover:bg-transparent py-2 h-auto min-h-auto"
type="button"
onClick={toggleKSpace}
>
{interfaceSettings.isShowKSpace ? (
<i className="pi pi-star-fill text-lg"></i>
) : (
<i className="pi pi-star text-lg"></i>
)}
</button>
</WdTooltipWrapper>
<WdTooltipWrapper content={isShowMinimap ? 'Hide minimap' : 'Show minimap'} position={TooltipPosition.left}>
<button <button
className="btn bg-transparent text-gray-400 hover:text-white border-transparent hover:bg-transparent py-2 h-auto min-h-auto" className="btn bg-transparent text-gray-400 hover:text-white border-transparent hover:bg-transparent py-2 h-auto min-h-auto"
type="button" type="button"
onClick={toggleMinimap} onClick={toggleMinimap}
> >
{interfaceSettings.isShowMinimap ? ( {isShowMinimap ? <i className="pi pi-eye text-lg"></i> : <i className="pi pi-eye-slash text-lg"></i>}
<i className="pi pi-eye text-lg"></i>
) : (
<i className="pi pi-eye-slash text-lg"></i>
)}
</button> </button>
</WdTooltipWrapper> </WdTooltipWrapper>

View File

@@ -24,7 +24,7 @@ export const MapWrapper = ({ refn }: MapWrapperProps) => {
update, update,
outCommand, outCommand,
data: { selectedConnections, selectedSystems, hubs, systems }, data: { selectedConnections, selectedSystems, hubs, systems },
interfaceSettings: { isShowMenu, isShowMinimap = STORED_INTERFACE_DEFAULT_VALUES.isShowMinimap }, interfaceSettings: { isShowMenu, isShowMinimap = STORED_INTERFACE_DEFAULT_VALUES.isShowMinimap, isShowKSpace },
} = useMapRootState(); } = useMapRootState();
const { open, ...systemContextProps } = useContextMenuSystemHandlers({ systems, hubs, outCommand }); const { open, ...systemContextProps } = useContextMenuSystemHandlers({ systems, hubs, outCommand });
@@ -99,6 +99,7 @@ export const MapWrapper = ({ refn }: MapWrapperProps) => {
onSelectionContextMenu={handleSystemMultipleContext} onSelectionContextMenu={handleSystemMultipleContext}
minimapClasses={!isShowMenu ? classes.MiniMap : undefined} minimapClasses={!isShowMenu ? classes.MiniMap : undefined}
isShowMinimap={isShowMinimap} isShowMinimap={isShowMinimap}
showKSpaceBG={isShowKSpace}
/> />
{openSettings != null && ( {openSettings != null && (

View File

@@ -5,3 +5,62 @@ export enum SESSION_KEY {
} }
export const GRADIENT_MENU_ACTIVE_CLASSES = 'bg-gradient-to-br from-transparent/10 to-fuchsia-300/10'; export const GRADIENT_MENU_ACTIVE_CLASSES = 'bg-gradient-to-br from-transparent/10 to-fuchsia-300/10';
export enum Regions {
Derelik = 10000001,
TheForge = 10000002,
Lonetrek = 10000016,
SinqLaison = 10000032,
Aridia = 10000054,
BlackRise = 10000069,
TheBleakLands = 10000038,
TheCitadel = 10000033,
Devoid = 10000036,
Domain = 10000043,
Essence = 10000064,
Everyshore = 10000037,
Genesis = 10000067,
Heimatar = 10000030,
Kador = 10000052,
Khanid = 10000049,
KorAzor = 10000065,
Metropolis = 10000042,
MoldenHeath = 10000028,
Placid = 10000048,
Solitude = 10000044,
TashMurkon = 10000020,
VergeVendor = 10000068,
}
export enum Spaces {
'Caldari' = 'Caldari',
'Gallente' = 'Gallente',
'Matar' = 'Matar',
'Amarr' = 'Amarr',
}
export const REGIONS_MAP: Record<number, Spaces> = {
[Regions.Derelik]: Spaces.Amarr,
[Regions.TheForge]: Spaces.Caldari,
[Regions.Lonetrek]: Spaces.Caldari,
[Regions.SinqLaison]: Spaces.Gallente,
[Regions.Aridia]: Spaces.Amarr,
[Regions.BlackRise]: Spaces.Caldari,
[Regions.TheBleakLands]: Spaces.Amarr,
[Regions.TheCitadel]: Spaces.Caldari,
[Regions.Devoid]: Spaces.Amarr,
[Regions.Domain]: Spaces.Amarr,
[Regions.Essence]: Spaces.Gallente,
[Regions.Everyshore]: Spaces.Gallente,
[Regions.Genesis]: Spaces.Amarr,
[Regions.Heimatar]: Spaces.Matar,
[Regions.Kador]: Spaces.Amarr,
[Regions.Khanid]: Spaces.Amarr,
[Regions.KorAzor]: Spaces.Amarr,
[Regions.Metropolis]: Spaces.Matar,
[Regions.MoldenHeath]: Spaces.Matar,
[Regions.Placid]: Spaces.Gallente,
[Regions.Solitude]: Spaces.Gallente,
[Regions.TashMurkon]: Spaces.Amarr,
[Regions.VergeVendor]: Spaces.Gallente,
};

View File

@@ -30,11 +30,13 @@ const INITIAL_DATA: MapRootData = {
type InterfaceStoredSettings = { type InterfaceStoredSettings = {
isShowMenu: boolean; isShowMenu: boolean;
isShowMinimap: boolean; isShowMinimap: boolean;
isShowKSpace: boolean;
}; };
export const STORED_INTERFACE_DEFAULT_VALUES: InterfaceStoredSettings = { export const STORED_INTERFACE_DEFAULT_VALUES: InterfaceStoredSettings = {
isShowMenu: false, isShowMenu: false,
isShowMinimap: true, isShowMinimap: true,
isShowKSpace: false,
}; };
export interface MapRootContextProps { export interface MapRootContextProps {
@@ -50,6 +52,7 @@ const MapRootContext = createContext<MapRootContextProps>({
update: () => {}, update: () => {},
data: { ...INITIAL_DATA }, data: { ...INITIAL_DATA },
mapRef: { current: null }, mapRef: { current: null },
// @ts-ignore
outCommand: async () => void 0, outCommand: async () => void 0,
interfaceSettings: STORED_INTERFACE_DEFAULT_VALUES, interfaceSettings: STORED_INTERFACE_DEFAULT_VALUES,
setInterfaceSettings: () => null, setInterfaceSettings: () => null,

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB