Skip to content

Commit

Permalink
Merge branch 'master' of github.com:crosshare-org/crosshare
Browse files Browse the repository at this point in the history
  • Loading branch information
mdirolf committed Apr 29, 2024
2 parents c14480c + 38e26f1 commit 917aaef
Show file tree
Hide file tree
Showing 12 changed files with 257 additions and 84 deletions.
7 changes: 2 additions & 5 deletions app/components/AlternateSolutionEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,8 @@ import {
} from '../lib/types';
import { logAsyncErrors } from '../lib/utils';
import { fromCells } from '../lib/viewableGrid';
import {
KeypressAction,
PasteAction,
gridInterfaceReducer,
} from '../reducers/gridReducer';
import { KeypressAction } from '../reducers/commonActions';
import { PasteAction, gridInterfaceReducer } from '../reducers/gridReducer';
import styles from './AlternateSolutionEditor.module.css';
import { GridView } from './Grid';
import { EscapeKey, Rebus } from './Icons';
Expand Down
3 changes: 1 addition & 2 deletions app/components/Builder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,11 @@ import {
getClueProps,
initialBuilderState,
} from '../reducers/builderReducer';
import { PuzzleAction } from '../reducers/commonActions';
import { KeypressAction, PuzzleAction } from '../reducers/commonActions';
import {
ClickedEntryAction,
CopyAction,
CutAction,
KeypressAction,
PasteAction,
} from '../reducers/gridReducer';
import { AuthProps } from './AuthHelpers';
Expand Down
3 changes: 2 additions & 1 deletion app/components/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import { FaAngleDoubleLeft, FaAngleDoubleRight } from 'react-icons/fa';
import { usePolyfilledResizeObserver } from '../lib/hooks';
import { KeyK } from '../lib/types';
import { clsx } from '../lib/utils';
import { KeypressAction, PasteAction } from '../reducers/gridReducer';
import { KeypressAction } from '../reducers/commonActions';
import { PasteAction } from '../reducers/gridReducer';
import { EmbedContext } from './EmbedContext';
import styles from './Page.module.css';

Expand Down
2 changes: 1 addition & 1 deletion app/components/Preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
getClueProps,
initialBuilderState,
} from '../reducers/builderReducer';
import { KeypressAction } from '../reducers/gridReducer';
import { KeypressAction } from '../reducers/commonActions';
import { AuthProps } from './AuthHelpers';
import { ClueList } from './ClueList';
import { ClueMode } from './ClueMode';
Expand Down
4 changes: 2 additions & 2 deletions app/components/Puzzle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ import {
getEntryToClueMap,
getRefs,
} from '../lib/viewableGrid';
import { PuzzleAction } from '../reducers/commonActions';
import { KeypressAction, PasteAction } from '../reducers/gridReducer';
import { KeypressAction, PuzzleAction } from '../reducers/commonActions';
import { PasteAction } from '../reducers/gridReducer';
import {
CheatAction,
LoadPlayAction,
Expand Down
2 changes: 1 addition & 1 deletion app/components/PuzzleStats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
builderReducer,
initialBuilderState,
} from '../reducers/builderReducer';
import { KeypressAction } from '../reducers/gridReducer';
import { KeypressAction } from '../reducers/commonActions';
import { ButtonAsLink } from './Buttons';
import { ClueList } from './ClueList';
import { CopyableInput } from './CopyableInput';
Expand Down
16 changes: 16 additions & 0 deletions app/lib/gridBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,22 @@ export function isInBounds<Entry extends EntryBase>(
);
}

export function isIndexInBounds<Entry extends EntryBase>(
grid: GridBase<Entry>,
index: number
): boolean {
return index >= 0 && index < grid.width * grid.height;
}

export function isInDirection(posA: PosAndDir, posB: Position): boolean {
switch (posA.dir) {
case Direction.Across:
return posA.row === posB.row;
case Direction.Down:
return posA.col === posB.col;
}
}

export function clampInBounds<Entry extends EntryBase>(
grid: GridBase<Entry>,
pos: PosAndDir
Expand Down
84 changes: 84 additions & 0 deletions app/lib/viewableGrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
cellIndex,
entriesFromCells,
entryAtPosition,
isInDirection,
isIndexInBounds,
posForIndex,
valAt,
} from './gridBase';
Expand All @@ -16,9 +18,11 @@ import {
BLOCK,
ClueT,
Direction,
EMPTY,
PosAndDir,
Position,
Symmetry,
isSamePosition,
} from './types';

export interface ViewableEntry extends EntryBase {
Expand Down Expand Up @@ -344,6 +348,86 @@ export function moveToNextEntry<Entry extends ViewableEntry>(
};
}

export function moveToEntryInActiveDirection<Entry extends ViewableEntry>(
grid: ViewableGrid<Entry>,
pos: PosAndDir,
reverse = false
): Position {
const [currentEntry] = entryAtPosition(grid, pos);
if (!currentEntry) {
return pos;
}

const { cells } = currentEntry;
const startCell = reverse ? cells[0] : cells[cells.length - 1];
if (!startCell) {
return pos;
}

const xincr = pos.dir === Direction.Across ? 1 : 0;
const yincr = pos.dir === Direction.Down ? 1 : 0;
let iincr = xincr + yincr * grid.width;
if (reverse) {
iincr *= -1;
}

let ci = cellIndex(grid, startCell) + iincr;
let newPos = posForIndex(grid, ci);
while (isIndexInBounds(grid, ci) && isInDirection(pos, newPos)) {
const [newEntry] = entryAtPosition(grid, { ...newPos, dir: pos.dir });
if (newEntry && newEntry !== currentEntry) {
return newPos;
}
newPos = posForIndex(grid, (ci += iincr));
}

return pos;
}

export function moveToEntry<Entry extends ViewableEntry>(
grid: ViewableGrid<Entry>,
pos: PosAndDir,
move: (grid: ViewableGrid<Entry>, active: Position) => Position
): Position {
let oldPos: Position = { ...pos };
let newPos = move(grid, oldPos);
while (!isSamePosition(newPos, oldPos)) {
const [newEntry] = entryAtPosition(grid, { ...newPos, dir: pos.dir });
if (newEntry) {
return newPos;
}
oldPos = newPos;
newPos = move(grid, oldPos);
}

return pos;
}

export function advanceTo<Entry extends ViewableEntry>(
grid: ViewableGrid<Entry>,
pos: PosAndDir,
newPos: Position,
wrongCells: Set<number>
): PosAndDir {
if (isSamePosition(pos, newPos)) {
return pos;
}

const { dir } = pos;
const [entry] = entryAtPosition(grid, { ...newPos, dir });
if (!entry) {
return pos;
}

for (const cell of entry.cells) {
if (valAt(grid, cell) === EMPTY || wrongCells.has(cellIndex(grid, cell))) {
return { ...cell, dir };
}
}

return { ...newPos, dir };
}

export function gridWithNewChar<
Entry extends ViewableEntry,
Grid extends ViewableGrid<Entry>
Expand Down
62 changes: 60 additions & 2 deletions app/reducers/builderReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Timestamp } from '../lib/timestamp';
import {
Direction,
EMPTY,
KeyK,
Position,
PrefillSquares,
PuzzleInProgressT,
Expand All @@ -17,9 +18,13 @@ import {
ViewableGrid,
fromCells,
gridEqual,
moveDown,
moveLeft,
moveRight,
moveUp,
} from '../lib/viewableGrid';
import { postEdit, validateGrid } from './builderUtils';
import { PuzzleAction } from './commonActions';
import { hasSelection, postEdit, validateGrid } from './builderUtils';
import { PuzzleAction, isKeypressAction } from './commonActions';
import {
GridInterfaceState,
closeRebus,
Expand Down Expand Up @@ -510,6 +515,59 @@ function _builderReducer(
state: BuilderState,
action: PuzzleAction
): BuilderState {
if (isKeypressAction(action)) {
const key = action.key;
if (key.k === KeyK.ShiftArrowRight) {
const { start, end } = hasSelection(state)
? state.selection
: emptySelection(state.active);
return {
...state,
wasEntryClick: false,
selection: {
start,
end: moveRight(state.grid, end),
},
};
} else if (key.k === KeyK.ShiftArrowLeft) {
const { start, end } = hasSelection(state)
? state.selection
: emptySelection(state.active);
return {
...state,
wasEntryClick: false,
selection: {
start,
end: moveLeft(state.grid, end),
},
};
} else if (key.k === KeyK.ShiftArrowUp) {
const { start, end } = hasSelection(state)
? state.selection
: emptySelection(state.active);
return {
...state,
wasEntryClick: false,
selection: {
start,
end: moveUp(state.grid, end),
},
};
} else if (key.k === KeyK.ShiftArrowDown) {
const { start, end } = hasSelection(state)
? state.selection
: emptySelection(state.active);
return {
...state,
wasEntryClick: false,
selection: {
start,
end: moveDown(state.grid, end),
},
};
}
return state;
}
if (isStartSelectionAction(action)) {
return {
...closeRebus(state),
Expand Down
12 changes: 12 additions & 0 deletions app/reducers/commonActions.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
import { Key } from '../lib/types';

export interface PuzzleAction {
type: string;
}

export interface KeypressAction extends PuzzleAction {
type: 'KEYPRESS';
key: Key;
}
export function isKeypressAction(
action: PuzzleAction
): action is KeypressAction {
return action.type === 'KEYPRESS';
}
Loading

0 comments on commit 917aaef

Please sign in to comment.