Sharing UI: invite by email, roles, read-only viewer mode (#17)
Build image / build-and-push (push) Successful in 8s
Build image / build-and-push (push) Successful in 8s
Co-authored-by: Steve Dudenhoeffer <[email protected]>
This commit was merged in pull request #36.
This commit is contained in:
@@ -34,11 +34,13 @@ export function GardenCanvas({
|
||||
objects,
|
||||
plantings,
|
||||
plantsById,
|
||||
canEdit,
|
||||
}: {
|
||||
garden: EditorGarden
|
||||
objects: EditorObject[]
|
||||
plantings: EditorPlanting[]
|
||||
plantsById: Map<number, Plant>
|
||||
canEdit: boolean
|
||||
}) {
|
||||
const svgRef = useRef<SVGSVGElement>(null)
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
@@ -108,7 +110,9 @@ export function GardenCanvas({
|
||||
// or exit focus mode, or just deselect.
|
||||
function onCanvasPointerDown(e: ReactPointerEvent) {
|
||||
const armed = useEditorStore.getState().armedKind
|
||||
if (armed) {
|
||||
// Defense in depth: a viewer can't place objects even if a stale armed kind
|
||||
// slipped through (the palette isn't rendered for them).
|
||||
if (armed && canEdit) {
|
||||
useEditorStore.getState().setArmedKind(null)
|
||||
const def = kindDef(armed)
|
||||
const rect = svgRef.current?.getBoundingClientRect()
|
||||
@@ -134,7 +138,7 @@ export function GardenCanvas({
|
||||
// armed for repeat-placement until Escape / Done).
|
||||
function onPlace(e: ReactPointerEvent) {
|
||||
e.stopPropagation()
|
||||
if (!focusedObject || !armedPlant || !focusedObject.plantable) return
|
||||
if (!canEdit || !focusedObject || !armedPlant || !focusedObject.plantable) return
|
||||
const rect = svgRef.current?.getBoundingClientRect()
|
||||
if (!rect) return
|
||||
const world = screenToWorld({ x: e.clientX - rect.left, y: e.clientY - rect.top }, viewport)
|
||||
@@ -188,14 +192,16 @@ export function GardenCanvas({
|
||||
onSelectPlop={selectPlanting}
|
||||
/>
|
||||
|
||||
{selectedObject && <SelectionOverlay object={selectedObject} gardenId={garden.id} svgRef={svgRef} />}
|
||||
{selectedPlop && selectedPlopObject && (
|
||||
{/* Edit handles are mounted only for editors/owners; viewers can still
|
||||
select to inspect (read-only), but never move/resize. */}
|
||||
{canEdit && selectedObject && <SelectionOverlay object={selectedObject} gardenId={garden.id} svgRef={svgRef} />}
|
||||
{canEdit && selectedPlop && selectedPlopObject && (
|
||||
<PlopOverlay plop={selectedPlop} object={selectedPlopObject} gardenId={garden.id} svgRef={svgRef} />
|
||||
)}
|
||||
|
||||
{/* Placement capture: a transparent sheet over the focused object while a
|
||||
plant is armed, so taps drop plops instead of selecting the object. */}
|
||||
{focusedObject && armedPlant && focusedObject.plantable && (
|
||||
{canEdit && focusedObject && armedPlant && focusedObject.plantable && (
|
||||
<g transform={objectTransform(focusedObject)}>
|
||||
<rect
|
||||
x={-halfFW}
|
||||
|
||||
Reference in New Issue
Block a user