Address review: disarm on tray-remove, cap load, tidy
Build image / build-and-push (push) Successful in 9s
Build image / build-and-push (push) Successful in 9s
- Removing the armed plant from the tray now disarms it, so placement doesn't continue for a plant that's no longer shown. - loadIds honors TRAY_MAX even if localStorage was hand-edited. - Consolidate the repeated `canEdit && plantable` toolbar guards into one nested conditional (3-model finding). - Rename the hook's SeedTray interface to SeedTrayState (avoids colliding with the SeedTray component) and the component prop plants → trayPlants. - Hoist ensurePlant to one call in onPickPlant; pass onPickPlant directly as onSelect; use ASCII "+" for the tray chip; document the FIFO eviction. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01JdQpdYYsTgtkJBxbcpAszi
This commit is contained in:
@@ -244,18 +244,26 @@ export function GardenEditorPage() {
|
||||
setArmedPlant(plant)
|
||||
}
|
||||
|
||||
// Removing the armed plant from the tray also disarms it, so placement doesn't
|
||||
// silently continue for a plant the user just cleared out.
|
||||
function removeFromTrayAndDisarm(id: number) {
|
||||
removeFromTray(id)
|
||||
if (armedPlant?.id === id) setArmedPlant(null)
|
||||
}
|
||||
|
||||
// The picker hands back the full Plant (from the whole catalog), so use it
|
||||
// directly rather than re-resolving against the garden's referenced-plant map —
|
||||
// a not-yet-placed plant isn't in that map, which used to silently abort the
|
||||
// pick (nothing armed, picker left open).
|
||||
// pick (nothing armed, picker left open). Picking (place OR change) makes sure
|
||||
// the plant renders and drops it into this garden's tray for quick reuse.
|
||||
function onPickPlant(plant: Plant) {
|
||||
if (!canEdit) return // defense in depth: viewers can't reach the picker anyway
|
||||
ensurePlant(plant)
|
||||
addToTray(plant)
|
||||
if (picker === 'change' && selectedPlop) {
|
||||
ensurePlant(plant)
|
||||
updatePlanting.mutate({ id: selectedPlop.id, version: selectedPlop.version, plantId: plant.id })
|
||||
} else {
|
||||
armPlant(plant) // 'place' mode: arm for repeat placement
|
||||
setArmedPlant(plant) // 'place' mode: arm for repeat placement
|
||||
}
|
||||
setPicker(null)
|
||||
}
|
||||
@@ -284,30 +292,34 @@ export function GardenEditorPage() {
|
||||
← {garden.name}
|
||||
</button>
|
||||
<span className="max-w-[8rem] truncate text-muted">{objectDisplayName(focusedObject)}</span>
|
||||
{canEdit && !focusedObject.plantable && <span className="text-xs text-muted">Not plantable</span>}
|
||||
{canEdit && focusedObject.plantable && (
|
||||
<SeedTray
|
||||
plants={trayPlants}
|
||||
armedPlantId={armedPlant?.id ?? null}
|
||||
onArm={armPlant}
|
||||
onRemove={removeFromTray}
|
||||
onOpenPicker={() => setPicker('place')}
|
||||
/>
|
||||
)}
|
||||
{canEdit && focusedObject.plantable && armedPlant && (
|
||||
<Button variant="ghost" className="px-2 py-1 text-xs" onClick={() => setArmedPlant(null)}>
|
||||
Done
|
||||
</Button>
|
||||
)}
|
||||
{canEdit && focusedObject.plantable && focusedPlops.length > 0 && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="px-2 py-1 text-xs text-red-600 dark:text-red-400"
|
||||
onClick={() => setClearing(true)}
|
||||
>
|
||||
Clear ({focusedPlops.length})
|
||||
</Button>
|
||||
)}
|
||||
{canEdit &&
|
||||
(focusedObject.plantable ? (
|
||||
<>
|
||||
<SeedTray
|
||||
trayPlants={trayPlants}
|
||||
armedPlantId={armedPlant?.id ?? null}
|
||||
onArm={armPlant}
|
||||
onRemove={removeFromTrayAndDisarm}
|
||||
onOpenPicker={() => setPicker('place')}
|
||||
/>
|
||||
{armedPlant && (
|
||||
<Button variant="ghost" className="px-2 py-1 text-xs" onClick={() => setArmedPlant(null)}>
|
||||
Done
|
||||
</Button>
|
||||
)}
|
||||
{focusedPlops.length > 0 && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="px-2 py-1 text-xs text-red-600 dark:text-red-400"
|
||||
onClick={() => setClearing(true)}
|
||||
>
|
||||
Clear ({focusedPlops.length})
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<span className="text-xs text-muted">Not plantable</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<GardenCanvas garden={garden} objects={objects} plantings={plantings} plantsById={plantsById} canEdit={canEdit} />
|
||||
@@ -355,7 +367,7 @@ export function GardenEditorPage() {
|
||||
<PlantPicker
|
||||
unit={garden.unitPref}
|
||||
onClose={() => setPicker(null)}
|
||||
onSelect={(p) => onPickPlant(p)}
|
||||
onSelect={onPickPlant}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user