@omercnet/paseo-queens 0.1.0-next.128.1 → 0.1.0-next.130.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/puzzle-selector.tsx +3 -3
- package/client/queens-board.tsx +38 -18
- package/client/queens-popover.tsx +3 -40
- package/package.json +10 -5
|
@@ -134,10 +134,10 @@ function createStyles(theme: PluginSurfaceProps["theme"], compact: boolean): Sel
|
|
|
134
134
|
flexDirection: "row",
|
|
135
135
|
flexWrap: "wrap",
|
|
136
136
|
justifyContent: "center",
|
|
137
|
-
gap: compact ?
|
|
137
|
+
gap: compact ? 6 : 12,
|
|
138
138
|
},
|
|
139
139
|
step: {
|
|
140
|
-
minWidth: compact ?
|
|
140
|
+
minWidth: compact ? 132 : 152,
|
|
141
141
|
minHeight: 44,
|
|
142
142
|
flexDirection: "row",
|
|
143
143
|
alignItems: "center",
|
|
@@ -161,7 +161,7 @@ function createStyles(theme: PluginSurfaceProps["theme"], compact: boolean): Sel
|
|
|
161
161
|
fontWeight: "500",
|
|
162
162
|
},
|
|
163
163
|
valueBlock: {
|
|
164
|
-
minWidth: compact ?
|
|
164
|
+
minWidth: compact ? 52 : 68,
|
|
165
165
|
flex: 1,
|
|
166
166
|
alignItems: "center",
|
|
167
167
|
gap: 1,
|
package/client/queens-board.tsx
CHANGED
|
@@ -32,18 +32,44 @@ type BoardLayout = {
|
|
|
32
32
|
|
|
33
33
|
type DragReplacement = "empty" | "excluded";
|
|
34
34
|
|
|
35
|
+
type DragSelection = {
|
|
36
|
+
readonly indexes: ReadonlySet<number>;
|
|
37
|
+
readonly replacement: DragReplacement;
|
|
38
|
+
};
|
|
39
|
+
|
|
35
40
|
type DragGesture = {
|
|
36
41
|
readonly startIndex: number;
|
|
37
|
-
|
|
38
|
-
|
|
42
|
+
indexes: Set<number>;
|
|
43
|
+
replacement: DragReplacement;
|
|
39
44
|
moved: boolean;
|
|
40
45
|
cancelled: boolean;
|
|
41
46
|
};
|
|
42
47
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
export function resolveDraggedCellState(
|
|
49
|
+
index: number,
|
|
50
|
+
persistedState: CellState,
|
|
51
|
+
dragSelection: DragSelection | null,
|
|
52
|
+
): CellState {
|
|
53
|
+
if (persistedState === "marked" || dragSelection === null || !dragSelection.indexes.has(index)) {
|
|
54
|
+
return persistedState;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (dragSelection.replacement === "empty") {
|
|
58
|
+
return persistedState === "excluded" ? "empty" : persistedState;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return persistedState === "empty" ? "excluded" : persistedState;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function collectDragIndexes(
|
|
65
|
+
cells: readonly CellState[],
|
|
66
|
+
selection: DragSelection,
|
|
67
|
+
): number[] {
|
|
68
|
+
return [...selection.indexes].filter((index) => {
|
|
69
|
+
const persistedState = cells[index] ?? "empty";
|
|
70
|
+
return resolveDraggedCellState(index, persistedState, selection) !== persistedState;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
47
73
|
|
|
48
74
|
type PendingTap = {
|
|
49
75
|
readonly releasedAt: number;
|
|
@@ -200,7 +226,7 @@ export function QueensBoard({
|
|
|
200
226
|
const cellsRef = useRef(cells);
|
|
201
227
|
const onSetCellsRef = useRef(onSetCells);
|
|
202
228
|
const onGestureActiveChangeRef = useRef(onGestureActiveChange);
|
|
203
|
-
const [dragPreview, setDragPreview] = useState<
|
|
229
|
+
const [dragPreview, setDragPreview] = useState<DragSelection | null>(null);
|
|
204
230
|
cellsRef.current = cells;
|
|
205
231
|
onSetCellsRef.current = onSetCells;
|
|
206
232
|
onGestureActiveChangeRef.current = onGestureActiveChange;
|
|
@@ -291,6 +317,7 @@ export function QueensBoard({
|
|
|
291
317
|
},
|
|
292
318
|
[dragEnabled, puzzle.size],
|
|
293
319
|
);
|
|
320
|
+
|
|
294
321
|
const finishGesture = useCallback(() => {
|
|
295
322
|
const gesture = gestureRef.current;
|
|
296
323
|
gestureRef.current = null;
|
|
@@ -309,11 +336,9 @@ export function QueensBoard({
|
|
|
309
336
|
pending?.cancel();
|
|
310
337
|
pendingTapsRef.current.delete(index);
|
|
311
338
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
: [...gesture.indexes];
|
|
316
|
-
onSetCellsRef.current(indexes, gesture.replacement);
|
|
339
|
+
|
|
340
|
+
const indexes = collectDragIndexes(cellsRef.current, gesture);
|
|
341
|
+
if (indexes.length > 0) onSetCellsRef.current(indexes, gesture.replacement);
|
|
317
342
|
}, [handleTapRelease]);
|
|
318
343
|
|
|
319
344
|
const cancelGesture = useCallback(() => {
|
|
@@ -330,13 +355,8 @@ export function QueensBoard({
|
|
|
330
355
|
{coordinates.map((column) => {
|
|
331
356
|
const index = row * puzzle.size + column;
|
|
332
357
|
const persistedState = cells[index] ?? "empty";
|
|
333
|
-
let state = persistedState;
|
|
334
|
-
if (dragPreview?.indexes.has(index)) {
|
|
335
|
-
if (dragPreview.replacement === "excluded" || persistedState === "excluded") {
|
|
336
|
-
state = dragPreview.replacement;
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
358
|
const region = puzzle.regions[index] ?? 0;
|
|
359
|
+
const state = resolveDraggedCellState(index, persistedState, dragPreview);
|
|
340
360
|
const conflicted = conflicts.has(index);
|
|
341
361
|
const markColor = solved
|
|
342
362
|
? theme.colors.statusSuccess
|
|
@@ -74,7 +74,6 @@ function QueensPopoverGame({
|
|
|
74
74
|
theme,
|
|
75
75
|
host,
|
|
76
76
|
layout,
|
|
77
|
-
close,
|
|
78
77
|
deck,
|
|
79
78
|
catalog,
|
|
80
79
|
}: PluginButtonContentProps & {
|
|
@@ -151,25 +150,6 @@ function QueensPopoverGame({
|
|
|
151
150
|
|
|
152
151
|
return (
|
|
153
152
|
<View style={styles.root}>
|
|
154
|
-
{!layout.compact ? (
|
|
155
|
-
<View style={styles.header}>
|
|
156
|
-
<View style={styles.titleRow}>
|
|
157
|
-
<GameMark size={22} color={theme.colors.accent} />
|
|
158
|
-
<Text accessibilityRole="header" style={styles.title}>
|
|
159
|
-
Queens
|
|
160
|
-
</Text>
|
|
161
|
-
</View>
|
|
162
|
-
<Pressable
|
|
163
|
-
accessibilityRole="button"
|
|
164
|
-
accessibilityLabel="Close Queens"
|
|
165
|
-
onPress={close}
|
|
166
|
-
style={styles.doneButton}
|
|
167
|
-
>
|
|
168
|
-
<Text style={styles.doneText}>Done</Text>
|
|
169
|
-
</Pressable>
|
|
170
|
-
</View>
|
|
171
|
-
) : null}
|
|
172
|
-
|
|
173
153
|
<View style={styles.metaRow}>
|
|
174
154
|
<Text style={styles.metaText}>
|
|
175
155
|
#{puzzleNumber}/{state.puzzles.length}
|
|
@@ -207,7 +187,7 @@ function QueensPopoverGame({
|
|
|
207
187
|
<QueensBoard
|
|
208
188
|
key={`${host.id}:${puzzle.id}:popover`}
|
|
209
189
|
dragEnabled={!layout.compact}
|
|
210
|
-
maxSize={layout.compact ? 296 :
|
|
190
|
+
maxSize={layout.compact ? 296 : 146}
|
|
211
191
|
puzzle={puzzle}
|
|
212
192
|
cells={progress.cells}
|
|
213
193
|
conflicts={conflicts}
|
|
@@ -252,28 +232,11 @@ function QueensPopoverGame({
|
|
|
252
232
|
function createStyles(theme: PluginButtonContentProps["theme"], compact: boolean) {
|
|
253
233
|
return StyleSheet.create({
|
|
254
234
|
root: {
|
|
255
|
-
width:
|
|
235
|
+
width: "100%",
|
|
256
236
|
alignSelf: "center",
|
|
257
237
|
alignItems: "center",
|
|
258
238
|
gap: compact ? 12 : 6,
|
|
259
239
|
},
|
|
260
|
-
header: {
|
|
261
|
-
width: "100%",
|
|
262
|
-
flexDirection: "row",
|
|
263
|
-
alignItems: "center",
|
|
264
|
-
justifyContent: "space-between",
|
|
265
|
-
gap: 12,
|
|
266
|
-
},
|
|
267
|
-
titleRow: {
|
|
268
|
-
flexDirection: "row",
|
|
269
|
-
alignItems: "center",
|
|
270
|
-
gap: 8,
|
|
271
|
-
},
|
|
272
|
-
title: {
|
|
273
|
-
color: theme.colors.foreground,
|
|
274
|
-
fontSize: 18,
|
|
275
|
-
fontWeight: "800",
|
|
276
|
-
},
|
|
277
240
|
doneButton: {
|
|
278
241
|
minHeight: 36,
|
|
279
242
|
justifyContent: "center",
|
|
@@ -307,7 +270,7 @@ function createStyles(theme: PluginButtonContentProps["theme"], compact: boolean
|
|
|
307
270
|
},
|
|
308
271
|
boardFrame: {
|
|
309
272
|
width: "100%",
|
|
310
|
-
maxWidth: compact ? 296 :
|
|
273
|
+
maxWidth: compact ? 296 : 146,
|
|
311
274
|
},
|
|
312
275
|
statusCard: {
|
|
313
276
|
minHeight: 30,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@omercnet/paseo-queens",
|
|
3
|
-
"version": "0.1.0-next.
|
|
3
|
+
"version": "0.1.0-next.130.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A cross-platform Queens logic puzzle for Paseo.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,17 +38,22 @@
|
|
|
38
38
|
"paseo-plugin.json"
|
|
39
39
|
],
|
|
40
40
|
"scripts": {
|
|
41
|
-
"check": "biome check .",
|
|
41
|
+
"check": "biome check --error-on-warnings .",
|
|
42
42
|
"import:puzzles": "node scripts/import-curated-puzzles.mjs",
|
|
43
|
-
"test": "
|
|
43
|
+
"test": "run-s test:ci:*",
|
|
44
44
|
"typecheck": "tsc --noEmit",
|
|
45
|
-
"verify:package": "npm pack --dry-run"
|
|
45
|
+
"verify:package": "npm pack --dry-run",
|
|
46
|
+
"check:write": "biome check --write .",
|
|
47
|
+
"test:ci:unit": "vitest run",
|
|
48
|
+
"build": "node ../.github/scripts/build-plugin.mjs"
|
|
46
49
|
},
|
|
47
50
|
"devDependencies": {
|
|
48
|
-
"@biomejs/biome": "^2.5.
|
|
51
|
+
"@biomejs/biome": "^2.5.14",
|
|
49
52
|
"@getpaseo/plugin": "0.9.0-beta.1",
|
|
53
|
+
"@getpaseo/server": "0.9.0-beta.1",
|
|
50
54
|
"@types/node": "^24.5.2",
|
|
51
55
|
"@types/react": "~19.2.0",
|
|
56
|
+
"npm-run-all2": "^9.0.3",
|
|
52
57
|
"react": "19.1.0",
|
|
53
58
|
"react-native": "0.81.5",
|
|
54
59
|
"typescript": "^7.0.0",
|