]> git.localhorst.tv Git - alttp.git/commitdiff
option to trash connectors master
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Thu, 29 May 2025 16:55:41 +0000 (18:55 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Thu, 29 May 2025 16:55:41 +0000 (18:55 +0200)
resources/js/components/zootr/MixedPoolsTracker.js
resources/sass/zootr.scss

index 071f0dd24283b5f4c37f0f341ace57962292a818..ee7f954ed323c808c7a3539d53e46b9f7e636cb0 100644 (file)
@@ -2780,14 +2780,19 @@ MapEntrance.propTypes = {
        }),
 };
 
        }),
 };
 
-const MapConnector = ({ from, to, via }) => {
+const MapConnector = ({ from, id, isTrash, to, via }) => {
+       const { onConnectorClick } = useTracker();
+
        const className = React.useMemo(() => {
                const cs = ['connector'];
        const className = React.useMemo(() => {
                const cs = ['connector'];
+               if (isTrash) cs.push('is-trash');
                if (via.length) cs.push('is-via');
                return cs.join(' ');
                if (via.length) cs.push('is-via');
                return cs.join(' ');
-       }, [via]);
+       }, [isTrash, via]);
+
        return <line
                className={className}
        return <line
                className={className}
+               onClick={() => onConnectorClick(id)}
                x1={from.pos.x}
                y1={from.pos.y}
                x2={to.pos.x}
                x1={from.pos.x}
                y1={from.pos.y}
                x2={to.pos.x}
@@ -2802,6 +2807,8 @@ MapConnector.propTypes = {
                        y: PropTypes.number,
                })
        }),
                        y: PropTypes.number,
                })
        }),
+       id: PropTypes.string,
+       isTrash: PropTypes.bool,
        to: PropTypes.shape({
                pos: PropTypes.shape({
                        x: PropTypes.number,
        to: PropTypes.shape({
                pos: PropTypes.shape({
                        x: PropTypes.number,
@@ -2856,6 +2863,7 @@ const MixedPoolsTracker = () => {
        const [connections, setConnections] = React.useState({});
        const [dragging, setDragging] = React.useState(null);
        const [prefs, setPrefs] = React.useState(initPrefs());
        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) => {
 
        const setConnection = React.useCallback((src, dst) => {
                setConnections((c) => {
@@ -2910,16 +2918,27 @@ const MixedPoolsTracker = () => {
                }
        }, [dragging, setConnection, setDragging]);
 
                }
        }, [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,
        const context = React.useMemo(() => ({
                connections,
                entrances,
                isDragging,
+               onConnectorClick,
                onMapEntranceClick,
                setConnection,
        }), [
                connections,
                entrances,
                isDragging,
                onMapEntranceClick,
                setConnection,
        }), [
                connections,
                entrances,
                isDragging,
+               onConnectorClick,
                onMapEntranceClick,
                setConnection,
        ]);
                onMapEntranceClick,
                setConnection,
        ]);
@@ -2977,14 +2996,18 @@ const MixedPoolsTracker = () => {
                        if (!fromMap) return;
                        const toMap = getMapEntrance(path.dst);
                        if (!toMap) return;
                        if (!fromMap) return;
                        const toMap = getMapEntrance(path.dst);
                        if (!toMap) return;
+                       const id = `${fromMap.id}-${toMap.id}`;
+                       const isTrash = trashConnectors.includes(id);
                        cs.push({
                        cs.push({
+                               id,
                                from: fromMap,
                                to: toMap,
                                via: path.via,
                                from: fromMap,
                                to: toMap,
                                via: path.via,
+                               isTrash,
                        });
                });
                return cs;
                        });
                });
                return cs;
-       }, [connections]);
+       }, [connections, trashConnectors]);
 
        const annotations = React.useMemo(() => {
                const annotate = [
 
        const annotations = React.useMemo(() => {
                const annotate = [
@@ -3018,14 +3041,14 @@ const MixedPoolsTracker = () => {
 
        const save = React.useCallback(() => {
                try {
 
        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);
                }
                        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 {
 
        const load = React.useCallback(() => {
                try {
@@ -3034,9 +3057,16 @@ const MixedPoolsTracker = () => {
                                toastr.error(t('general.loadError'));
                                return;
                        }
                                toastr.error(t('general.loadError'));
                                return;
                        }
-                       const { connections } = JSON.parse(dump);
+                       const { connections, trashConnectors } = JSON.parse(dump);
                        if (connections) {
                                setConnections(connections);
                        if (connections) {
                                setConnections(connections);
+                       } else {
+                               setConnections({});
+                       }
+                       if (trashConnectors) {
+                               setTrashConnectors(trashConnectors);
+                       } else {
+                               setTrashConnectors([]);
                        }
                        toastr.success(t('general.loadSuccess'));
                } catch (e) {
                        }
                        toastr.success(t('general.loadSuccess'));
                } catch (e) {
@@ -3048,11 +3078,12 @@ const MixedPoolsTracker = () => {
        const reset = React.useCallback(() => {
                try {
                        setConnections({});
        const reset = React.useCallback(() => {
                try {
                        setConnections({});
+                       setTrashConnectors([]);
                        toastr.success(t('general.resetSuccess'));
                } catch (e) {
                        toastr.error(t('general.resetError'));
                }
                        toastr.success(t('general.resetSuccess'));
                } catch (e) {
                        toastr.error(t('general.resetError'));
                }
-       }, [setConnections, t]);
+       }, [t]);
 
        const togglePref = React.useCallback((which) => {
                setPrefs((oldPrefs) => {
 
        const togglePref = React.useCallback((which) => {
                setPrefs((oldPrefs) => {
@@ -3129,42 +3160,50 @@ const MixedPoolsTracker = () => {
                                        onClick={() => { setDragging(null); }}
                                        onContextMenu={(e) => { e.preventDefault(); e.stopPropagation(); }}
                                >
                                        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
                                        {prefs.showConnectors ?
                                                <g title="connectors">
                                                        {connectors.map((c) =>
                                                                <MapConnector
-                                                                       key={`${c.from.id}-${c.to.id}`}
+                                                                       key={c.id}
                                                                        from={c.from}
                                                                        from={c.from}
+                                                                       id={c.id}
+                                                                       isTrash={c.isTrash}
                                                                        to={c.to}
                                                                        via={c.via}
                                                                />
                                                        )}
                                                </g>
                                        : null}
                                                                        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) =>
                                        {prefs.showWarps ?
                                                <g title="anotations">
                                                        {annotations.map((a) =>
index 1af50bf237419324d5983d5f675475ebe8de9659..e83468d9bd7f2e3a74994657c05d30a7700e8747 100644 (file)
                }
                .connector {
                        stroke: #cc0000;
                }
                .connector {
                        stroke: #cc0000;
-                       pointer-events: none;
                        &.is-via {
                                stroke-dasharray: 3 3;
                        }
                        &.is-via {
                                stroke-dasharray: 3 3;
                        }
+                       &.is-trash {
+                               stroke: #000000;
+                               opacity: 0.2;
+                       }
+                       &:hover {
+                               filter: drop-shadow(0 0 1px #000000) drop-shadow(0 0 2px #000000);
+                               opacity: 1;
+                               stroke-width: 3px;
+                       }
                }
                .annotation {
                        pointer-events: none;
                }
                .annotation {
                        pointer-events: none;