import { Map } from '@/hooks/Mapper/components/map/Map.tsx'; import { useCallback, useRef, useState } from 'react'; import { OutCommand, OutCommandHandler, SolarSystemConnection } from '@/hooks/Mapper/types'; import { MapRootData, useMapRootState } from '@/hooks/Mapper/mapRootProvider'; import { OnMapAddSystemCallback, OnMapSelectionChange } from '@/hooks/Mapper/components/map/map.types.ts'; import isEqual from 'lodash.isequal'; import { ContextMenuSystem, useContextMenuSystemHandlers } from '@/hooks/Mapper/components/contexts'; import { SystemCustomLabelDialog, SystemLinkSignatureDialog, SystemSettingsDialog, } from '@/hooks/Mapper/components/mapInterface/components'; import classes from './MapWrapper.module.scss'; import { Connections } from '@/hooks/Mapper/components/mapRootContent/components/Connections'; import { ContextMenuSystemMultiple, useContextMenuSystemMultipleHandlers } from '../contexts/ContextMenuSystemMultiple'; import { getSystemById } from '@/hooks/Mapper/helpers'; import { Node, XYPosition } from 'reactflow'; import { Commands } from '@/hooks/Mapper/types/mapHandlers.ts'; import { emitMapEvent, useMapEventListener } from '@/hooks/Mapper/events'; import { STORED_INTERFACE_DEFAULT_VALUES } from '@/hooks/Mapper/mapRootProvider/MapRootProvider'; import { useDeleteSystems } from '@/hooks/Mapper/components/contexts/hooks'; import { useCommonMapEventProcessor } from '@/hooks/Mapper/components/mapWrapper/hooks/useCommonMapEventProcessor.ts'; import { AddSystemDialog, SearchOnSubmitCallback, } from '@/hooks/Mapper/components/mapInterface/components/AddSystemDialog'; // TODO: INFO - this component needs for abstract work with Map instance export const MapWrapper = () => { const { update, outCommand, data: { selectedConnections, selectedSystems, hubs, systems }, interfaceSettings: { isShowMenu, isShowMinimap = STORED_INTERFACE_DEFAULT_VALUES.isShowMinimap, isShowKSpace, isThickConnections, isShowBackgroundPattern, isSoftBackground, }, } = useMapRootState(); const { deleteSystems } = useDeleteSystems(); const { mapRef, runCommand } = useCommonMapEventProcessor(); const { open, ...systemContextProps } = useContextMenuSystemHandlers({ systems, hubs, outCommand }); const { handleSystemMultipleContext, ...systemMultipleCtxProps } = useContextMenuSystemMultipleHandlers(); const [openSettings, setOpenSettings] = useState(null); const [openLinkSignatures, setOpenLinkSignatures] = useState(null); const [openCustomLabel, setOpenCustomLabel] = useState(null); const [openAddSystem, setOpenAddSystem] = useState(null); const [selectedConnection, setSelectedConnection] = useState(null); const ref = useRef({ selectedConnections, selectedSystems, systemContextProps, systems, deleteSystems }); ref.current = { selectedConnections, selectedSystems, systemContextProps, systems, deleteSystems }; useMapEventListener(event => { switch (event.name) { case Commands.linkSignatureToSystem: setOpenLinkSignatures(event.data); return true; } runCommand(event); }); const onSelectionChange: OnMapSelectionChange = useCallback( ({ systems, connections }) => { const { selectedConnections, selectedSystems } = ref.current; const newData: Partial> = {}; if (!isEqual(systems, selectedSystems)) { newData.selectedSystems = systems; } if (!isEqual(connections, selectedConnections)) { newData.selectedConnections = connections; } update(newData); }, [update], ); const handleCommand: OutCommandHandler = useCallback( event => { switch (event.type) { case OutCommand.openSettings: setOpenSettings(event.data.system_id); break; case OutCommand.linkSignatureToSystem: setOpenLinkSignatures(event.data); break; default: return outCommand(event); } // @ts-ignore return new Promise(resolve => resolve(null)); }, [outCommand], ); const handleSystemContextMenu = useCallback( (ev: any, systemId: string) => { const { selectedSystems, systems } = ref.current; if (selectedSystems.length > 1) { const systemsInfo: Node[] = selectedSystems.map(x => ({ data: getSystemById(systems, x), id: x }) as Node); handleSystemMultipleContext(ev, systemsInfo); return; } open(ev, systemId); }, [open], ); const handleConnectionDbClick = useCallback((e: SolarSystemConnection) => setSelectedConnection(e), []); const handleManualDelete = useCallback((toDelete: string[]) => { const restDel = toDelete.filter(x => ref.current.systems.some(y => y.id === x)); if (restDel.length > 0) { ref.current.deleteSystems(restDel); } }, []); const onAddSystem: OnMapAddSystemCallback = useCallback(({ coordinates }) => { setOpenAddSystem(coordinates); }, []); const handleSubmitAddSystem: SearchOnSubmitCallback = useCallback( async item => { if (ref.current.systems.some(x => x.system_static_info.solar_system_id === item.value)) { emitMapEvent({ name: Commands.centerSystem, data: item.value.toString(), }); return; } await outCommand({ type: OutCommand.manualAddSystem, data: { coordinates: openAddSystem, solar_system_id: item.value }, }); }, [openAddSystem, outCommand], ); return ( <> {openSettings != null && ( setOpenSettings(null)} /> )} {openCustomLabel != null && ( setOpenCustomLabel(null)} /> )} {openLinkSignatures != null && ( setOpenLinkSignatures(null)} /> )} setOpenAddSystem(null)} onSubmit={handleSubmitAddSystem} /> setSelectedConnection(null)} /> { systemContextProps.systemId && setOpenSettings(systemContextProps.systemId); }} onCustomLabelDialog={() => { const { systemContextProps } = ref.current; systemContextProps.systemId && setOpenCustomLabel(systemContextProps.systemId); }} /> ); };