Skip to content

Commit

Permalink
Bug fixes for QFP
Browse files Browse the repository at this point in the history
  • Loading branch information
hlysine committed Jan 27, 2025
1 parent 4c16cef commit 0f06963
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 44 deletions.
14 changes: 12 additions & 2 deletions src/client/components/EditControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import { useGrid } from '../contexts/GridContext.tsx';
import { cn } from '../../client/uiHelper.ts';
import { useHotkeys } from 'react-hotkeys-hook';
import { useEdit } from '../contexts/EditContext.tsx';
import { useSearch } from '@tanstack/react-router';
import { Compressor, GridData, Serializer } from '@logic-pad/core/index.ts';

export default memo(function EditControls() {
const { grid, setGrid, setGridRaw } = useGrid();
const { undoStack, redoStack, undo: undoEdit, redo: redoEdit } = useEdit();
const search = useSearch({ from: undefined, strict: false });

const undo = () => {
const result = undoEdit(grid);
Expand All @@ -19,8 +22,15 @@ export default memo(function EditControls() {
if (result) setGridRaw(result);
};

const restart = () => {
const reset = grid.resetTiles();
const restart = async () => {
let reset: GridData;
if ('d' in search && search.d) {
reset = grid.withTiles(
Serializer.parsePuzzle(await Compressor.decompress(search.d)).grid.tiles
);
} else {
reset = grid.resetTiles();
}
if (reset === grid) return;
setGrid(reset);
};
Expand Down
29 changes: 15 additions & 14 deletions src/client/configs/parts/SolvePathEditorModal.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { memo, useEffect, useState } from 'react';
import { cn } from '../../uiHelper';
import EmbedContext from '../../contexts/EmbedContext';
import GridContext, { GridConsumer, useGrid } from '../../contexts/GridContext';
import GridContext, { GridConsumer } from '../../contexts/GridContext';
import DisplayContext from '../../contexts/DisplayContext';
import GridStateContext from '../../contexts/GridStateContext';
import { Color, Position } from '@logic-pad/core/data/primitives';
import PerfectionRule, {
instance as perfectionInstance,
} from '@logic-pad/core/data/rules/perfectionRule';
import PerfectionRule from '@logic-pad/core/data/rules/perfectionRule';
import PerfectionScreen from '../../screens/PerfectionScreen';
import ForesightRule, {
instance as foresightInstance,
Expand Down Expand Up @@ -50,14 +48,6 @@ function SolvePathUpdater({
return null;
}

function DialogClose({ setOpen }: { setOpen: (open: boolean) => void }) {
const { grid } = useGrid();
useEffect(() => {
if (!grid.findRule(r => r.id === perfectionInstance.id)) setOpen(false);
}, [grid, setOpen]);
return null;
}

function prepareGrid(
grid: GridData,
respectSolvePath: boolean
Expand Down Expand Up @@ -103,6 +93,16 @@ function prepareGrid(
}
}

function lockGrid(grid: GridData): GridData {
return grid.withTiles(tiles =>
tiles.map(row =>
row.map(tile =>
tile.exists && tile.color !== Color.Gray ? tile.withFixed(true) : tile
)
)
);
}

export default memo(function SolvePathEditorModal({
solvePath,
setSolvePath,
Expand Down Expand Up @@ -140,13 +140,14 @@ export default memo(function SolvePathEditorModal({
<EditContext>
<GridStateContext>
<GridContext
grid={() => prepareGrid(outerGrid, true).grid}
grid={() =>
lockGrid(prepareGrid(outerGrid, true).grid)
}
solution={() => prepareGrid(outerGrid, true).solution}
metadata={metadata}
>
<PerfectionScreen>
<EmbedLoader solvePath={solvePath} />
<DialogClose setOpen={setOpen} />
<SolvePathUpdater
oldSolvePath={tempSolvePath}
setSolvePath={setTempSolvePath}
Expand Down
2 changes: 1 addition & 1 deletion src/client/contexts/EditContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default memo(function EditContext({
setLastGrid(grid);
return;
}
if (lastGrid === grid) return;
if (lastGrid.equals(grid)) return;
addToUndoStack(lastGrid);
setLastGrid(grid);
setRedoStack([]);
Expand Down
11 changes: 8 additions & 3 deletions src/client/contexts/GridContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export default memo(function GridContext({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const setGridRaw: GridContext['setGridRaw'] = (newGrid, sol) => {
const invokeSetGrid = (newGrid: GridData, sol?: GridData | null) => {
newGrid.symbols.forEach(list => {
list.forEach(symbol => {
if (handlesSetGrid(symbol)) {
Expand All @@ -87,9 +87,15 @@ export default memo(function GridContext({
);
}
});
return newGrid;
};

const setGridRaw = (newGrid: GridData, sol?: GridData | null) => {
newGrid = invokeSetGrid(newGrid, sol);
setGrid(newGrid);
if (sol !== undefined) setSolution(sol);
setState(validateGrid(newGrid, sol === undefined ? solution : sol));
return newGrid;
};

return (
Expand All @@ -99,8 +105,7 @@ export default memo(function GridContext({
solution,
metadata,
setGrid: (grid, sol) => {
recordEdit(grid);
setGridRaw(grid, sol);
recordEdit(setGridRaw(grid, sol));
},
setGridRaw,
setMetadata,
Expand Down
21 changes: 21 additions & 0 deletions src/client/instructions/parts/BanPerfectionRulePart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useEffect } from 'react';
import { useGrid } from '../../contexts/GridContext';
import { instance as perfectionInstance } from '@logic-pad/core/data/rules/perfectionRule';

export default function BanPerfectionRulePart() {
const { grid, solution, setGridRaw } = useGrid();

useEffect(() => {
if (grid.findRule(r => r.id === perfectionInstance.id)) {
setGridRaw(
grid.withRules(rules =>
rules.filter(r => r.id !== perfectionInstance.id)
),
solution?.withRules(rules =>
rules.filter(r => r.id !== perfectionInstance.id)
)
);
}
}, [grid, solution, setGridRaw]);
return null;
}
25 changes: 1 addition & 24 deletions src/client/instructions/parts/PerfectionControlsPart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,19 @@ import { useGrid } from '../../contexts/GridContext';
import { useHotkeys } from 'react-hotkeys-hook';
import { useSolvePath } from '../../contexts/SolvePathContext';
import { useDelta } from 'react-delta-hooks';
import { useRouterState } from '@tanstack/react-router';

export interface PerfectionControlsPartProps {
instruction: PerfectionRule;
}

export default memo(function PerfectionControlsPart() {
const { grid, solution, setGridRaw } = useGrid();
const { grid, setGridRaw } = useGrid();
const { state } = useGridState();
const { undo } = useEdit();
const { solvePath, setSolvePath, visualizeSolvePath, setVisualizeSolvePath } =
useSolvePath();
const [tooltip, setTooltip] = useState<string | null>(null);

const router = useRouterState();

useEffect(() => {
if (router.location.pathname !== '/perfection') {
if (grid.findRule(r => r.id === perfectionInstance.id)) {
setGridRaw(
grid.withRules(rules =>
rules.filter(r => r.id !== perfectionInstance.id)
),
solution?.withRules(rules =>
rules.filter(r => r.id !== perfectionInstance.id)
)
);
}
}
}, [router.location.pathname, grid, solution, setGridRaw]);

useEffect(() => {
if (tooltip) {
const timeout = window.setTimeout(() => setTooltip(null), 2000);
Expand All @@ -65,11 +47,6 @@ export default memo(function PerfectionControlsPart() {
if (!gridDelta) return;
if (!gridDelta.prev) return;
if (gridDelta.prev === gridDelta.curr) return;
console.log(
'Comparing grid delta',
{ width: gridDelta.prev.width, height: gridDelta.prev.height },
{ width: gridDelta.curr.width, height: gridDelta.curr.height }
);
const positionsRemoved: Position[] = [];
const positionsAdded: Position[] = [];
let newSolvePath = solvePath.slice();
Expand Down
2 changes: 2 additions & 0 deletions src/client/screens/PerfectionScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import DocumentTitle from '../components/DocumentTitle';
import EditControls from '../components/EditControls';
import ThreePaneLayout from '../components/ThreePaneLayout';
import TouchControls from '../components/TouchControls';
import { GridConsumer } from '../contexts/GridContext';
Expand Down Expand Up @@ -40,6 +41,7 @@ export default function PerfectionScreen({ children }: PerfectionScreenProps) {
)}
</GridConsumer>
<TouchControls />
<EditControls />
</>
}
center={<MainGrid useToolboxClick={false} />}
Expand Down
2 changes: 2 additions & 0 deletions src/client/screens/PuzzleEditorScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { useEmbed } from '../contexts/EmbedContext';
import PuzzleChecklist from '../editor/PuzzleChecklist';
import InstructionPartOutlet from '../instructions/InstructionPartOutlet';
import { PartPlacement } from '../instructions/parts/types';
import BanPerfectionRulePart from '../instructions/parts/BanPerfectionRulePart';

export interface PuzzleEditorScreenProps {
children?: React.ReactNode;
Expand Down Expand Up @@ -54,6 +55,7 @@ export default memo(function PuzzleEditorScreen({
</div>
<TouchControls />
<EditControls />
<BanPerfectionRulePart />
</>
}
center={
Expand Down
2 changes: 2 additions & 0 deletions src/client/screens/SolveScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { GridConsumer } from '../contexts/GridContext';
import MainGrid from '../grid/MainGrid';
import InstructionList from '../instructions/InstructionList';
import InstructionPartOutlet from '../instructions/InstructionPartOutlet';
import BanPerfectionRulePart from '../instructions/parts/BanPerfectionRulePart';
import { PartPlacement } from '../instructions/parts/types';
import Metadata from '../metadata/Metadata';

Expand Down Expand Up @@ -43,6 +44,7 @@ export default function SolveScreen({ children }: SolveScreenProps) {
{children}
<TouchControls />
<EditControls />
<BanPerfectionRulePart />
</>
}
center={<MainGrid useToolboxClick={false} />}
Expand Down

0 comments on commit 0f06963

Please sign in to comment.