}),
};
-const MapConnector = ({ from, to, via }) => {
+const MapConnector = ({ from, id, isTrash, to, via }) => {
+ const { onConnectorClick } = useTracker();
+
const className = React.useMemo(() => {
const cs = ['connector'];
+ if (isTrash) cs.push('is-trash');
if (via.length) cs.push('is-via');
return cs.join(' ');
- }, [via]);
+ }, [isTrash, via]);
+
return <line
className={className}
+ onClick={() => onConnectorClick(id)}
x1={from.pos.x}
y1={from.pos.y}
x2={to.pos.x}
y: PropTypes.number,
})
}),
+ id: PropTypes.string,
+ isTrash: PropTypes.bool,
to: PropTypes.shape({
pos: PropTypes.shape({
x: PropTypes.number,
const [connections, setConnections] = React.useState({});
const [dragging, setDragging] = React.useState(null);
const [prefs, setPrefs] = React.useState(initPrefs());
+ const [trashConnectors, setTrashConnectors] = React.useState([]);
const setConnection = React.useCallback((src, dst) => {
setConnections((c) => {
}
}, [dragging, setConnection, setDragging]);
+ const onConnectorClick = React.useCallback((id) => {
+ setTrashConnectors((tc) => {
+ if (tc.includes(id)) {
+ return tc.filter((tid) => tid !== id);
+ }
+ return [...tc, id];
+ });
+ }, []);
+
const context = React.useMemo(() => ({
connections,
entrances,
isDragging,
+ onConnectorClick,
onMapEntranceClick,
setConnection,
}), [
connections,
entrances,
isDragging,
+ onConnectorClick,
onMapEntranceClick,
setConnection,
]);
if (!fromMap) return;
const toMap = getMapEntrance(path.dst);
if (!toMap) return;
+ const id = `${fromMap.id}-${toMap.id}`;
+ const isTrash = trashConnectors.includes(id);
cs.push({
+ id,
from: fromMap,
to: toMap,
via: path.via,
+ isTrash,
});
});
return cs;
- }, [connections]);
+ }, [connections, trashConnectors]);
const annotations = React.useMemo(() => {
const annotate = [
const save = React.useCallback(() => {
try {
- const dump = JSON.stringify({ connections });
+ const dump = JSON.stringify({ connections, trashConnectors });
localStorage.setItem('zootr.mixed-pools-tracker-save', dump);
toastr.success(t('general.saveSuccess'));
} catch (e) {
toastr.error(t('general.saveError'));
console.error(e);
}
- }, [connections, t]);
+ }, [connections, t, trashConnectors]);
const load = React.useCallback(() => {
try {
toastr.error(t('general.loadError'));
return;
}
- const { connections } = JSON.parse(dump);
+ const { connections, trashConnectors } = JSON.parse(dump);
if (connections) {
setConnections(connections);
+ } else {
+ setConnections({});
+ }
+ if (trashConnectors) {
+ setTrashConnectors(trashConnectors);
+ } else {
+ setTrashConnectors([]);
}
toastr.success(t('general.loadSuccess'));
} catch (e) {
const reset = React.useCallback(() => {
try {
setConnections({});
+ setTrashConnectors([]);
toastr.success(t('general.resetSuccess'));
} catch (e) {
toastr.error(t('general.resetError'));
}
- }, [setConnections, t]);
+ }, [t]);
const togglePref = React.useCallback((which) => {
setPrefs((oldPrefs) => {
onClick={() => { setDragging(null); }}
onContextMenu={(e) => { e.preventDefault(); e.stopPropagation(); }}
>
- {MAPS.map((map) =>
- <g className="area" key={map.id} title={map.name}>
- <image
- href={map.bg.src}
- pointerEvents="none"
- x={map.bg.pos.x} y={map.bg.pos.y}
- width={map.bg.size.x}
- style={{ opacity: prefs.showMaps ? 1 : 0.25 }}
- />
- {map.labelPos && prefs.showLabels ?
- <text
- className="area-label"
- x={map.labelPos.x}
- y={map.labelPos.y}
- fill={map.color}
- >
- {map.short}
- </text>
- : null}
- {prefs.showEntrances ? map.entrances.map((entrance) =>
- <MapEntrance key={entrance.id} entrance={entrance} />
- ) : null}
- </g>
- )}
+ <g className="background">
+ {MAPS.map((map) =>
+ <g className="area" key={map.id} title={map.name}>
+ <image
+ href={map.bg.src}
+ pointerEvents="none"
+ x={map.bg.pos.x} y={map.bg.pos.y}
+ width={map.bg.size.x}
+ style={{ opacity: prefs.showMaps ? 1 : 0.25 }}
+ />
+ {map.labelPos && prefs.showLabels ?
+ <text
+ className="area-label"
+ x={map.labelPos.x}
+ y={map.labelPos.y}
+ fill={map.color}
+ >
+ {map.short}
+ </text>
+ : null}
+ </g>
+ )}
+ </g>
{prefs.showConnectors ?
<g title="connectors">
{connectors.map((c) =>
<MapConnector
- key={`${c.from.id}-${c.to.id}`}
+ key={c.id}
from={c.from}
+ id={c.id}
+ isTrash={c.isTrash}
to={c.to}
via={c.via}
/>
)}
</g>
: null}
+ {MAPS.map((map) =>
+ <g className="area" key={map.id} title={map.name}>
+ {prefs.showEntrances ? map.entrances.map((entrance) =>
+ <MapEntrance key={entrance.id} entrance={entrance} />
+ ) : null}
+ </g>
+ )}
{prefs.showWarps ?
<g title="anotations">
{annotations.map((a) =>