@omercnet/paseo-queens 0.1.0-next.129.1 → 0.1.0-next.133.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/README.md +6 -20
- package/client/puzzle-selector.tsx +3 -3
- package/client/queens-board.tsx +38 -18
- package/client/queens-popover.tsx +3 -40
- package/package.json +12 -16
- package/paseo-plugin.json +1 -1
package/README.md
CHANGED
|
@@ -60,7 +60,7 @@ npm run import:puzzles
|
|
|
60
60
|
|
|
61
61
|
## Install
|
|
62
62
|
|
|
63
|
-
### Paseo 0.9
|
|
63
|
+
### Paseo 0.9
|
|
64
64
|
|
|
65
65
|
Install the published npm package on the daemon host:
|
|
66
66
|
|
|
@@ -75,20 +75,6 @@ paseo plugin update queens --check
|
|
|
75
75
|
paseo plugin update queens
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
### Paseo 0.8
|
|
79
|
-
|
|
80
|
-
Install from this monorepo:
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
paseo plugin install omercnet/paseo-plugins:queens
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
Or install a local checkout by absolute path on the daemon host:
|
|
87
|
-
|
|
88
|
-
```bash
|
|
89
|
-
paseo plugin install /absolute/path/to/paseo-plugins/queens
|
|
90
|
-
```
|
|
91
|
-
|
|
92
78
|
Open **Queens** from the sidebar or Command Center. Open any agent session to use the composer mini-game.
|
|
93
79
|
|
|
94
80
|
## Develop
|
|
@@ -96,10 +82,10 @@ Open **Queens** from the sidebar or Command Center. Open any agent session to us
|
|
|
96
82
|
Use an isolated Paseo home and explicit host. Never reload this development checkout against your default daemon.
|
|
97
83
|
|
|
98
84
|
```bash
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
85
|
+
bun install
|
|
86
|
+
bun run check
|
|
87
|
+
bun run typecheck
|
|
88
|
+
bun run test
|
|
103
89
|
|
|
104
90
|
paseo daemon config set daemon.listen 127.0.0.1:6802 --home /tmp/queens-dev
|
|
105
91
|
paseo daemon config set daemon.relay.enabled false --home /tmp/queens-dev
|
|
@@ -113,7 +99,7 @@ Release Please owns package versions, changelog generation, component tags, and
|
|
|
113
99
|
|
|
114
100
|
## Requirements
|
|
115
101
|
|
|
116
|
-
- Paseo
|
|
102
|
+
- Paseo `>=0.8.0 <0.10.0`
|
|
117
103
|
- Plugins enabled on the target daemon
|
|
118
104
|
- React Native-compatible Paseo client on web, desktop, iOS, or Android
|
|
119
105
|
|
|
@@ -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.133.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A cross-platform Queens logic puzzle for Paseo.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"publishConfig": {
|
|
18
18
|
"access": "public"
|
|
19
19
|
},
|
|
20
|
-
"packageManager": "
|
|
20
|
+
"packageManager": "bun@1.4.2",
|
|
21
21
|
"engines": {
|
|
22
22
|
"node": ">=24"
|
|
23
23
|
},
|
|
@@ -38,26 +38,22 @@
|
|
|
38
38
|
"paseo-plugin.json"
|
|
39
39
|
],
|
|
40
40
|
"scripts": {
|
|
41
|
-
"check": "biome check
|
|
41
|
+
"check": "biome check .",
|
|
42
|
+
"check:write": "biome check --write .",
|
|
42
43
|
"import:puzzles": "node scripts/import-curated-puzzles.mjs",
|
|
43
|
-
"test": "run
|
|
44
|
+
"test": "vitest run",
|
|
44
45
|
"typecheck": "tsc --noEmit",
|
|
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
|
+
"verify:package": "npm pack --dry-run"
|
|
49
47
|
},
|
|
50
48
|
"devDependencies": {
|
|
51
|
-
"@biomejs/biome": "^2.5.
|
|
52
|
-
"@getpaseo/plugin": "0.9.0
|
|
53
|
-
"@
|
|
54
|
-
"@types/
|
|
55
|
-
"@types/react": "~19.2.0",
|
|
56
|
-
"npm-run-all2": "^9.0.3",
|
|
49
|
+
"@biomejs/biome": "^2.5.10",
|
|
50
|
+
"@getpaseo/plugin": "0.9.0",
|
|
51
|
+
"@types/node": "^24.10.1",
|
|
52
|
+
"@types/react": "^19.2.18",
|
|
57
53
|
"react": "19.1.0",
|
|
58
54
|
"react-native": "0.81.5",
|
|
59
|
-
"typescript": "^7.0.
|
|
55
|
+
"typescript": "^7.0.2",
|
|
60
56
|
"vitest": "^5.0.0",
|
|
61
|
-
"zod": "
|
|
57
|
+
"zod": "4.4.3"
|
|
62
58
|
}
|
|
63
59
|
}
|
package/paseo-plugin.json
CHANGED