mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-12 02:35:42 +00:00
Initial commit
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
.ConnectionTimeEOL {
|
||||
background-image: linear-gradient(207deg, transparent, #7452c3e3);
|
||||
}
|
||||
|
||||
.ConnectionFrigate {
|
||||
background-image: linear-gradient(207deg, transparent, #325d88);
|
||||
}
|
||||
|
||||
.ConnectionSave {
|
||||
background-image: linear-gradient(207deg, transparent, rgba(155, 102, 45, 0.85));
|
||||
}
|
||||
|
||||
.SelectedItem {
|
||||
background-color: rgba(98, 98, 98, 0.33);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
import React, { RefObject, useMemo } from 'react';
|
||||
import { ContextMenu } from 'primereact/contextmenu';
|
||||
import { PrimeIcons } from 'primereact/api';
|
||||
import { MenuItem } from 'primereact/menuitem';
|
||||
import { Edge } from '@reactflow/core/dist/esm/types/edges';
|
||||
import { MassState, ShipSizeStatus, SolarSystemConnection, TimeStatus } from '@/hooks/Mapper/types';
|
||||
import clsx from 'clsx';
|
||||
import classes from './ContextMenuConnection.module.scss';
|
||||
import { MASS_STATE_NAMES, MASS_STATE_NAMES_ORDER } from '@/hooks/Mapper/components/map/constants.ts';
|
||||
|
||||
export interface ContextMenuConnectionProps {
|
||||
contextMenuRef: RefObject<ContextMenu>;
|
||||
onDeleteConnection(): void;
|
||||
onChangeTimeState(): void;
|
||||
onChangeMassState(state: MassState): void;
|
||||
onChangeShipSizeStatus(state: ShipSizeStatus): void;
|
||||
onToggleMassSave(isLocked: boolean): void;
|
||||
onHide(): void;
|
||||
edge?: Edge<SolarSystemConnection>;
|
||||
}
|
||||
|
||||
export const ContextMenuConnection: React.FC<ContextMenuConnectionProps> = ({
|
||||
contextMenuRef,
|
||||
onDeleteConnection,
|
||||
onChangeTimeState,
|
||||
onChangeMassState,
|
||||
onChangeShipSizeStatus,
|
||||
onToggleMassSave,
|
||||
onHide,
|
||||
edge,
|
||||
}) => {
|
||||
const items: MenuItem[] = useMemo(() => {
|
||||
if (!edge) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const isFrigateSize = edge.data?.ship_size_type === ShipSizeStatus.small;
|
||||
|
||||
return [
|
||||
{
|
||||
label: `EOL`,
|
||||
className: clsx({
|
||||
[classes.ConnectionTimeEOL]: edge.data?.time_status === TimeStatus.eol,
|
||||
}),
|
||||
icon: PrimeIcons.CLOCK,
|
||||
command: onChangeTimeState,
|
||||
},
|
||||
{
|
||||
label: `Frigate`,
|
||||
className: clsx({
|
||||
[classes.ConnectionFrigate]: isFrigateSize,
|
||||
}),
|
||||
icon: PrimeIcons.CLOUD,
|
||||
command: () =>
|
||||
onChangeShipSizeStatus(
|
||||
edge.data?.ship_size_type === ShipSizeStatus.small ? ShipSizeStatus.normal : ShipSizeStatus.small,
|
||||
),
|
||||
},
|
||||
{
|
||||
label: `Save mass`,
|
||||
className: clsx({
|
||||
[classes.ConnectionSave]: edge.data?.locked,
|
||||
}),
|
||||
icon: PrimeIcons.LOCK,
|
||||
command: () => onToggleMassSave(!edge.data?.locked),
|
||||
},
|
||||
...(!isFrigateSize
|
||||
? [
|
||||
{
|
||||
label: `Mass status`,
|
||||
icon: PrimeIcons.CHART_PIE,
|
||||
items: MASS_STATE_NAMES_ORDER.map(x => ({
|
||||
label: MASS_STATE_NAMES[x],
|
||||
className: clsx({
|
||||
[classes.SelectedItem]: edge.data?.mass_status === x,
|
||||
}),
|
||||
command: () => onChangeMassState(x),
|
||||
})),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
label: 'Disconnect',
|
||||
icon: PrimeIcons.TRASH,
|
||||
command: onDeleteConnection,
|
||||
},
|
||||
];
|
||||
}, [edge, onChangeTimeState, onDeleteConnection, onChangeMassState, onChangeShipSizeStatus]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContextMenu model={items} ref={contextMenuRef} onHide={onHide} breakpoint="767px" />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './ContextMenuConnection.tsx';
|
||||
export * from './useContextMenuConnectionHandlers.ts';
|
||||
@@ -0,0 +1,126 @@
|
||||
import { EdgeMouseHandler } from 'reactflow';
|
||||
import { useCallback, useRef, useState } from 'react';
|
||||
import { ContextMenu } from 'primereact/contextmenu';
|
||||
import { useMapState } from '../../MapProvider.tsx';
|
||||
import { OutCommand } from '@/hooks/Mapper/types/mapHandlers.ts';
|
||||
import { Edge } from '@reactflow/core/dist/esm/types/edges';
|
||||
import { MassState, ShipSizeStatus, SolarSystemConnection, TimeStatus } from '@/hooks/Mapper/types';
|
||||
import { ctxManager } from '@/hooks/Mapper/utils/contextManager.ts';
|
||||
|
||||
export const useContextMenuConnectionHandlers = () => {
|
||||
const contextMenuRef = useRef<ContextMenu | null>(null);
|
||||
const { outCommand } = useMapState();
|
||||
const [edge, setEdge] = useState<Edge<SolarSystemConnection>>();
|
||||
|
||||
const ref = useRef({ edge, outCommand });
|
||||
ref.current = { edge, outCommand };
|
||||
|
||||
const handleConnectionContext: EdgeMouseHandler = (ev, edge_) => {
|
||||
setEdge(edge_);
|
||||
ev.preventDefault();
|
||||
ctxManager.next('ctxConn', contextMenuRef.current);
|
||||
contextMenuRef.current?.show(ev);
|
||||
};
|
||||
|
||||
const onDeleteConnection = () => {
|
||||
if (!edge) {
|
||||
return;
|
||||
}
|
||||
|
||||
outCommand({ type: OutCommand.manualDeleteConnection, data: { source: edge.source, target: edge.target } });
|
||||
setEdge(undefined);
|
||||
};
|
||||
|
||||
const onChangeTimeState = () => {
|
||||
if (!edge || !edge.data) {
|
||||
return;
|
||||
}
|
||||
|
||||
outCommand({
|
||||
type: OutCommand.updateConnectionTimeStatus,
|
||||
data: {
|
||||
source: edge.source,
|
||||
target: edge.target,
|
||||
value: edge.data.time_status === TimeStatus.default ? TimeStatus.eol : TimeStatus.default,
|
||||
},
|
||||
});
|
||||
setEdge(undefined);
|
||||
};
|
||||
|
||||
const onChangeMassState = useCallback((status: MassState) => {
|
||||
const { edge, outCommand } = ref.current;
|
||||
|
||||
if (!edge) {
|
||||
return;
|
||||
}
|
||||
|
||||
outCommand({
|
||||
type: OutCommand.updateConnectionMassStatus,
|
||||
data: {
|
||||
source: edge.source,
|
||||
target: edge.target,
|
||||
value: status,
|
||||
},
|
||||
});
|
||||
}, []);
|
||||
|
||||
const onChangeShipSizeStatus = useCallback((status: ShipSizeStatus) => {
|
||||
const { edge, outCommand } = ref.current;
|
||||
|
||||
if (!edge) {
|
||||
return;
|
||||
}
|
||||
|
||||
outCommand({
|
||||
type: OutCommand.updateConnectionShipSizeType,
|
||||
data: {
|
||||
source: edge.source,
|
||||
target: edge.target,
|
||||
value: status,
|
||||
},
|
||||
});
|
||||
|
||||
outCommand({
|
||||
type: OutCommand.updateConnectionMassStatus,
|
||||
data: {
|
||||
source: edge.source,
|
||||
target: edge.target,
|
||||
value: MassState.normal,
|
||||
},
|
||||
});
|
||||
}, []);
|
||||
|
||||
const onToggleMassSave = useCallback((locked: boolean) => {
|
||||
const { edge, outCommand } = ref.current;
|
||||
|
||||
if (!edge) {
|
||||
return;
|
||||
}
|
||||
|
||||
outCommand({
|
||||
type: OutCommand.updateConnectionLocked,
|
||||
data: {
|
||||
source: edge.source,
|
||||
target: edge.target,
|
||||
value: locked,
|
||||
},
|
||||
});
|
||||
}, []);
|
||||
|
||||
const onHide = useCallback(() => {
|
||||
setEdge(undefined);
|
||||
}, []);
|
||||
|
||||
return {
|
||||
handleConnectionContext,
|
||||
edge,
|
||||
|
||||
contextMenuRef,
|
||||
onDeleteConnection,
|
||||
onChangeTimeState,
|
||||
onChangeMassState,
|
||||
onChangeShipSizeStatus,
|
||||
onToggleMassSave,
|
||||
onHide,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user