Refactor builder store and remove wall store
Refactor builder store and remove wall store - Consolidated wall-related state management into the builder store by removing the useWallStore. - Added new properties and setters for wall attributes (thickness, height, materials) in the builder store. - Introduced SelectedWallProperties and WallProperties components for managing wall properties in the sidebar. - Created a new floor store for managing floor-related state. - Added a wall asset store for managing wall assets. - Implemented a zone store for managing zones and their properties. - Updated sidebar styles for better layout and appearance.
This commit is contained in:
@@ -3,74 +3,58 @@ import { create } from 'zustand';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
|
||||
interface BuilderState {
|
||||
// Common properties
|
||||
|
||||
// Point & Line Interaction
|
||||
hoveredPoint: Point | null;
|
||||
snappedPoint: Point | null;
|
||||
snappedPosition: [number, number, number] | null;
|
||||
|
||||
hoveredLine: [Point, Point] | null;
|
||||
|
||||
// Wall
|
||||
|
||||
// Wall Settings
|
||||
selectedWall: Object3D | null;
|
||||
wallThickness: number;
|
||||
wallHeight: number;
|
||||
outsideMaterial: string;
|
||||
insideMaterial: string;
|
||||
|
||||
setWallThickness: (thickness: number) => void;
|
||||
setWallHeight: (height: number) => void;
|
||||
setWallMaterial: (material: string, side: 'inside' | 'outside') => void;
|
||||
|
||||
// Aisle
|
||||
|
||||
// Aisle General
|
||||
selectedAisle: Object3D | null;
|
||||
|
||||
aisleType: AisleTypes;
|
||||
aisleWidth: number;
|
||||
aisleColor: AisleColors;
|
||||
|
||||
// Dashed aisle properties
|
||||
// Aisle Specific Styles
|
||||
dashLength: number;
|
||||
gapLength: number;
|
||||
|
||||
// Dotted aisle properties
|
||||
dotRadius: number;
|
||||
|
||||
// Arrows aisle properties
|
||||
aisleLength: number;
|
||||
|
||||
// Junction aisle properties
|
||||
isFlipped: boolean;
|
||||
|
||||
// Setters for common properties
|
||||
|
||||
// Setters - Point/Line
|
||||
setHoveredPoint: (point: Point | null) => void;
|
||||
setSnappedPoint: (point: Point | null) => void;
|
||||
setSnappedPosition: (position: [number, number, number] | null) => void;
|
||||
|
||||
setHoveredLine: (line: [Point, Point] | null) => void;
|
||||
|
||||
setSelectedAisle: (aisle: Object3D | null) => void;
|
||||
// Setters - Wall
|
||||
setSelectedWall: (wall: Object3D | null) => void;
|
||||
setWallThickness: (thickness: number) => void;
|
||||
setWallHeight: (height: number) => void;
|
||||
setWallMaterial: (material: string, side: 'inside' | 'outside') => void;
|
||||
|
||||
// Setters - Aisle General
|
||||
setSelectedAisle: (aisle: Object3D | null) => void;
|
||||
setAisleType: (type: AisleTypes) => void;
|
||||
setAisleWidth: (width: number) => void;
|
||||
setAisleColor: (color: AisleColors) => void;
|
||||
|
||||
// Setters for dashed aisle
|
||||
// Setters - Aisle Specific
|
||||
setDashLength: (length: number) => void;
|
||||
setGapLength: (length: number) => void;
|
||||
|
||||
// Setters for dotted aisle
|
||||
setDotRadius: (radius: number) => void;
|
||||
|
||||
// Setters for arrows aisle
|
||||
setAisleLength: (length: number) => void;
|
||||
|
||||
// Setters for junction aisle
|
||||
setIsFlipped: (isFlipped: boolean) => void;
|
||||
|
||||
// Batch setters
|
||||
// Batch Setters
|
||||
setDashedAisleProperties: (width: number, dashLength: number, gapLength: number) => void;
|
||||
setDottedAisleProperties: (width: number, dotRadius: number, gapLength: number) => void;
|
||||
setArrowsAisleProperties: (width: number, aisleLength: number, gapLength: number) => void;
|
||||
@@ -79,20 +63,62 @@ interface BuilderState {
|
||||
|
||||
export const useBuilderStore = create<BuilderState>()(
|
||||
immer((set) => ({
|
||||
// Default values
|
||||
|
||||
// === Defaults ===
|
||||
hoveredPoint: null,
|
||||
snappedPoint: null,
|
||||
snappedPosition: null,
|
||||
|
||||
hoveredLine: null,
|
||||
|
||||
// Wall
|
||||
|
||||
selectedWall: null,
|
||||
wallThickness: 0.5,
|
||||
wallHeight: 7,
|
||||
outsideMaterial: 'Default Material',
|
||||
insideMaterial: 'Default Material',
|
||||
insideMaterial: 'Material 1',
|
||||
|
||||
selectedAisle: null,
|
||||
aisleType: 'solid-aisle',
|
||||
aisleWidth: 0.1,
|
||||
aisleColor: 'yellow',
|
||||
|
||||
dashLength: 0.5,
|
||||
gapLength: 0.3,
|
||||
dotRadius: 0.1,
|
||||
aisleLength: 0.6,
|
||||
isFlipped: false,
|
||||
|
||||
// === Setters: Point/Line ===
|
||||
|
||||
setHoveredPoint: (point: Point | null) => {
|
||||
set((state) => {
|
||||
state.hoveredPoint = point;
|
||||
});
|
||||
},
|
||||
|
||||
setSnappedPoint: (point: Point | null) => {
|
||||
set((state) => {
|
||||
state.snappedPoint = point;
|
||||
});
|
||||
},
|
||||
|
||||
setSnappedPosition: (position: [number, number, number] | null) => {
|
||||
set((state) => {
|
||||
state.snappedPosition = position;
|
||||
});
|
||||
},
|
||||
|
||||
setHoveredLine: (line: [Point, Point] | null) => {
|
||||
set((state) => {
|
||||
state.hoveredLine = line;
|
||||
})
|
||||
},
|
||||
|
||||
// === Setters: Wall ===
|
||||
|
||||
setSelectedWall: (wall: Object3D | null) => {
|
||||
set((state) => {
|
||||
state.selectedWall = wall;
|
||||
})
|
||||
},
|
||||
|
||||
setWallThickness: (thickness: number) => {
|
||||
set((state) => {
|
||||
@@ -113,44 +139,7 @@ export const useBuilderStore = create<BuilderState>()(
|
||||
});
|
||||
},
|
||||
|
||||
// Aisle
|
||||
|
||||
selectedAisle: null,
|
||||
|
||||
aisleType: 'solid-aisle',
|
||||
aisleWidth: 0.1,
|
||||
aisleColor: 'yellow',
|
||||
dashLength: 0.5,
|
||||
gapLength: 0.3,
|
||||
dotRadius: 0.1,
|
||||
aisleLength: 0.6,
|
||||
isFlipped: false,
|
||||
|
||||
// Individual setters
|
||||
|
||||
setHoveredPoint: (point: Point | null) => {
|
||||
set((state) => {
|
||||
state.hoveredPoint = point;
|
||||
});
|
||||
},
|
||||
|
||||
setHoveredLine: (line: [Point, Point] | null) => {
|
||||
set((state) => {
|
||||
state.hoveredLine = line;
|
||||
})
|
||||
},
|
||||
|
||||
setSnappedPoint: (point: Point | null) => {
|
||||
set((state) => {
|
||||
state.snappedPoint = point;
|
||||
});
|
||||
},
|
||||
|
||||
setSnappedPosition: (position: [number, number, number] | null) => {
|
||||
set((state) => {
|
||||
state.snappedPosition = position;
|
||||
});
|
||||
},
|
||||
// === Setters: Aisle General ===
|
||||
|
||||
setSelectedAisle: (aisle: Object3D | null) => {
|
||||
set((state) => {
|
||||
@@ -163,73 +152,78 @@ export const useBuilderStore = create<BuilderState>()(
|
||||
state.aisleType = type;
|
||||
});
|
||||
},
|
||||
|
||||
setAisleWidth: (width) => {
|
||||
set((state) => {
|
||||
state.aisleWidth = width;
|
||||
});
|
||||
},
|
||||
|
||||
setAisleColor: (color) => {
|
||||
set((state) => {
|
||||
state.aisleColor = color;
|
||||
});
|
||||
},
|
||||
|
||||
// === Setters: Aisle Specific ===
|
||||
|
||||
setDashLength: (length) => {
|
||||
set((state) => {
|
||||
state.dashLength = length;
|
||||
});
|
||||
},
|
||||
|
||||
setGapLength: (length) => {
|
||||
set((state) => {
|
||||
state.gapLength = length;
|
||||
});
|
||||
},
|
||||
|
||||
setDotRadius: (radius) => {
|
||||
set((state) => {
|
||||
state.dotRadius = radius;
|
||||
});
|
||||
},
|
||||
|
||||
setAisleLength: (length) => {
|
||||
set((state) => {
|
||||
state.aisleLength = length;
|
||||
});
|
||||
},
|
||||
|
||||
setIsFlipped: (isFlipped) => {
|
||||
set((state) => {
|
||||
state.isFlipped = isFlipped;
|
||||
});
|
||||
},
|
||||
|
||||
// Batch setters
|
||||
setDashedAisleProperties: (width, dashLength, gapLength) => {
|
||||
set((state) => {
|
||||
state.aisleType = 'dashed-aisle';
|
||||
state.aisleWidth = width;
|
||||
state.dashLength = dashLength;
|
||||
state.gapLength = gapLength;
|
||||
});
|
||||
},
|
||||
setDottedAisleProperties: (width, dotRadius, gapLength) => {
|
||||
set((state) => {
|
||||
state.aisleType = 'dotted-aisle';
|
||||
state.aisleWidth = width;
|
||||
state.dotRadius = dotRadius;
|
||||
state.gapLength = gapLength;
|
||||
});
|
||||
},
|
||||
setArrowsAisleProperties: (width, aisleLength, gapLength) => {
|
||||
set((state) => {
|
||||
state.aisleType = 'arrows-aisle';
|
||||
state.aisleWidth = width;
|
||||
state.aisleLength = aisleLength;
|
||||
state.gapLength = gapLength;
|
||||
});
|
||||
},
|
||||
setAisleProperties: (type, width, color) => {
|
||||
set((state) => {
|
||||
state.aisleType = type;
|
||||
state.aisleWidth = width;
|
||||
state.aisleColor = color;
|
||||
});
|
||||
}
|
||||
// === Batch Setters ===
|
||||
|
||||
setDashedAisleProperties: (width, dashLength, gapLength) => set((state) => {
|
||||
state.aisleType = 'dashed-aisle';
|
||||
state.aisleWidth = width;
|
||||
state.dashLength = dashLength;
|
||||
state.gapLength = gapLength;
|
||||
}),
|
||||
|
||||
setDottedAisleProperties: (width, dotRadius, gapLength) => set((state) => {
|
||||
state.aisleType = 'dotted-aisle';
|
||||
state.aisleWidth = width;
|
||||
state.dotRadius = dotRadius;
|
||||
state.gapLength = gapLength;
|
||||
}),
|
||||
|
||||
setArrowsAisleProperties: (width, aisleLength, gapLength) => set((state) => {
|
||||
state.aisleType = 'arrows-aisle';
|
||||
state.aisleWidth = width;
|
||||
state.aisleLength = aisleLength;
|
||||
state.gapLength = gapLength;
|
||||
}),
|
||||
|
||||
setAisleProperties: (type, width, color) => set((state) => {
|
||||
state.aisleType = type;
|
||||
state.aisleWidth = width;
|
||||
state.aisleColor = color;
|
||||
})
|
||||
}))
|
||||
);
|
||||
);
|
||||
|
||||
90
app/src/store/builder/useFloorStore.ts
Normal file
90
app/src/store/builder/useFloorStore.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { create } from 'zustand';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
|
||||
interface FloorStore {
|
||||
floors: Floor[];
|
||||
setFloors: (floors: Floor[]) => void;
|
||||
addFloor: (floor: Floor) => void;
|
||||
updateFloor: (uuid: string, updated: Partial<Floor>) => void;
|
||||
removeFloor: (uuid: string) => void;
|
||||
removePointFromFloors: (pointUuid: string) => void;
|
||||
clearFloors: () => void;
|
||||
setIsBeveled: (uuid: string, isBeveled: boolean) => void;
|
||||
setBevelStrength: (uuid: string, strength: number) => void;
|
||||
setDepth: (uuid: string, depth: number) => void;
|
||||
setMaterial: (uuid: string, sideMaterial: string, topMaterial: string) => void;
|
||||
|
||||
getFloorById: (uuid: string) => Floor | undefined;
|
||||
}
|
||||
|
||||
export const createFloorStore = () => {
|
||||
return create<FloorStore>()(
|
||||
immer((set, get) => ({
|
||||
floors: [],
|
||||
|
||||
setFloors: (floors) => set(state => {
|
||||
state.floors = floors;
|
||||
}),
|
||||
|
||||
addFloor: (floor) => set(state => {
|
||||
state.floors.push(floor);
|
||||
}),
|
||||
|
||||
updateFloor: (uuid, updated) => set(state => {
|
||||
const floor = state.floors.find(f => f.floorUuid === uuid);
|
||||
if (floor) {
|
||||
Object.assign(floor, updated);
|
||||
}
|
||||
}),
|
||||
|
||||
removeFloor: (uuid) => set(state => {
|
||||
state.floors = state.floors.filter(f => f.floorUuid !== uuid);
|
||||
}),
|
||||
|
||||
removePointFromFloors: (pointUuid) => set(state => {
|
||||
for (const floor of state.floors) {
|
||||
floor.points = floor.points.filter(p => p.pointUuid !== pointUuid);
|
||||
}
|
||||
}),
|
||||
|
||||
clearFloors: () => set(state => {
|
||||
state.floors = [];
|
||||
}),
|
||||
|
||||
setIsBeveled: (uuid, isBeveled) => set(state => {
|
||||
const floor = state.floors.find(f => f.floorUuid === uuid);
|
||||
if (floor) {
|
||||
floor.isBeveled = isBeveled;
|
||||
}
|
||||
}),
|
||||
|
||||
setBevelStrength: (uuid, strength) => set(state => {
|
||||
const floor = state.floors.find(f => f.floorUuid === uuid);
|
||||
if (floor) {
|
||||
floor.bevelStrength = strength;
|
||||
}
|
||||
}),
|
||||
|
||||
setDepth: (uuid, depth) => set(state => {
|
||||
const floor = state.floors.find(f => f.floorUuid === uuid);
|
||||
if (floor) {
|
||||
floor.floorDepth = depth;
|
||||
}
|
||||
}),
|
||||
|
||||
setMaterial: (uuid, sideMaterial, topMaterial) => set(state => {
|
||||
const floor = state.floors.find(f => f.floorUuid === uuid);
|
||||
if (floor) {
|
||||
floor.sideMaterial = sideMaterial;
|
||||
floor.topMaterial = topMaterial;
|
||||
}
|
||||
}),
|
||||
|
||||
getFloorById: (uuid) => {
|
||||
return get().floors.find(f => f.floorUuid === uuid);
|
||||
},
|
||||
}))
|
||||
);
|
||||
};
|
||||
|
||||
export type FloorStoreType = ReturnType<typeof createFloorStore>;
|
||||
82
app/src/store/builder/useWallAssetStore.ts
Normal file
82
app/src/store/builder/useWallAssetStore.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { create } from 'zustand';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
|
||||
interface WallAssetStore {
|
||||
wallAssets: WallAsset[];
|
||||
setWallAssets: (assets: WallAsset[]) => void;
|
||||
addWallAsset: (asset: WallAsset) => void;
|
||||
updateWallAsset: (uuid: string, updated: Partial<WallAsset>) => void;
|
||||
removeWallAsset: (uuid: string) => void;
|
||||
clearWallAssets: () => void;
|
||||
|
||||
setVisibility: (uuid: string, isVisible: boolean) => void;
|
||||
setLock: (uuid: string, isLocked: boolean) => void;
|
||||
setOpacity: (uuid: string, opacity: number) => void;
|
||||
|
||||
getWallAssetById: (uuid: string) => WallAsset | undefined;
|
||||
getAssetsByWall: (wallUuid: string) => WallAsset[];
|
||||
}
|
||||
|
||||
export const createWallAssetStore = () => {
|
||||
return create<WallAssetStore>()(
|
||||
immer((set, get) => ({
|
||||
wallAssets: [],
|
||||
|
||||
setWallAssets: (assets) => set(state => {
|
||||
state.wallAssets = assets;
|
||||
}),
|
||||
|
||||
addWallAsset: (asset) => set(state => {
|
||||
state.wallAssets.push(asset);
|
||||
}),
|
||||
|
||||
updateWallAsset: (uuid, updated) => set(state => {
|
||||
const asset = state.wallAssets.find(a => a.modelUuid === uuid);
|
||||
if (asset) {
|
||||
Object.assign(asset, updated);
|
||||
}
|
||||
}),
|
||||
|
||||
removeWallAsset: (uuid) => set(state => {
|
||||
state.wallAssets = state.wallAssets.filter(a => a.modelUuid !== uuid);
|
||||
}),
|
||||
|
||||
clearWallAssets: () => {
|
||||
set(state => {
|
||||
state.wallAssets = [];
|
||||
})
|
||||
},
|
||||
|
||||
setVisibility: (uuid, isVisible) => set(state => {
|
||||
const asset = state.wallAssets.find(a => a.modelUuid === uuid);
|
||||
if (asset) {
|
||||
asset.isVisible = isVisible;
|
||||
}
|
||||
}),
|
||||
|
||||
setLock: (uuid, isLocked) => set(state => {
|
||||
const asset = state.wallAssets.find(a => a.modelUuid === uuid);
|
||||
if (asset) {
|
||||
asset.isLocked = isLocked;
|
||||
}
|
||||
}),
|
||||
|
||||
setOpacity: (uuid, opacity) => set(state => {
|
||||
const asset = state.wallAssets.find(a => a.modelUuid === uuid);
|
||||
if (asset) {
|
||||
asset.opacity = opacity;
|
||||
}
|
||||
}),
|
||||
|
||||
getWallAssetById: (uuid) => {
|
||||
return get().wallAssets.find(a => a.modelUuid === uuid);
|
||||
},
|
||||
|
||||
getAssetsByWall: (wallUuid) => {
|
||||
return get().wallAssets.filter(a => a.wallUuid === wallUuid);
|
||||
},
|
||||
}))
|
||||
);
|
||||
};
|
||||
|
||||
export type WallAssetStoreType = ReturnType<typeof createWallAssetStore>;
|
||||
211
app/src/store/builder/useWallStore.ts
Normal file
211
app/src/store/builder/useWallStore.ts
Normal file
@@ -0,0 +1,211 @@
|
||||
import { create } from 'zustand';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
|
||||
interface WallStore {
|
||||
walls: Wall[];
|
||||
setWalls: (walls: Wall[]) => void;
|
||||
addWall: (wall: Wall) => void;
|
||||
updateWall: (uuid: string, updated: Partial<Wall>) => void;
|
||||
removeWall: (uuid: string) => void;
|
||||
clearWalls: () => void;
|
||||
removeWallByPoints: (Points: [Point, Point]) => Wall | undefined;
|
||||
addDecal: (wallUuid: string, decal: Decal) => void;
|
||||
updateDecal: (decalUuid: string, decal: Decal) => void;
|
||||
removeDecal: (decalUuid: string) => void;
|
||||
updateDecalPosition: (decalUuid: string, position: [number, number, number]) => void;
|
||||
updateDecalRotation: (decalUuid: string, rotation: number) => void;
|
||||
updateDecalScale: (decalUuid: string, scale: number) => void;
|
||||
|
||||
removePoint: (pointUuid: string) => Wall[];
|
||||
setPosition: (pointUuid: string, position: [number, number, number]) => void;
|
||||
setLayer: (pointUuid: string, layer: number) => void;
|
||||
|
||||
getWallById: (uuid: string) => Wall | undefined;
|
||||
getWallByPointId: (uuid: string) => Wall | undefined;
|
||||
getWallByPoints: (points: Point[]) => Wall | undefined;
|
||||
getWallPointById: (uuid: string) => Point | undefined;
|
||||
getConnectedPoints: (uuid: string) => Point[];
|
||||
}
|
||||
|
||||
export const createWallStore = () => {
|
||||
return create<WallStore>()(
|
||||
immer((set, get) => ({
|
||||
walls: [],
|
||||
|
||||
setWalls: (walls) => set((state) => {
|
||||
state.walls = walls;
|
||||
}),
|
||||
|
||||
addWall: (wall) => set((state) => {
|
||||
state.walls.push(wall);
|
||||
}),
|
||||
|
||||
updateWall: (uuid, updated) => set((state) => {
|
||||
const wall = state.walls.find(w => w.wallUuid === uuid);
|
||||
if (wall) {
|
||||
Object.assign(wall, updated);
|
||||
}
|
||||
}),
|
||||
|
||||
removeWall: (uuid) => set((state) => {
|
||||
state.walls = state.walls.filter(w => w.wallUuid !== uuid);
|
||||
}),
|
||||
|
||||
clearWalls: () => {
|
||||
set((state) => {
|
||||
state.walls = [];
|
||||
})
|
||||
},
|
||||
|
||||
removeWallByPoints: (points) => {
|
||||
let removedWall: Wall | undefined;
|
||||
const [pointA, pointB] = points;
|
||||
|
||||
set((state) => {
|
||||
state.walls = state.walls.filter(wall => {
|
||||
const wallPoints = wall.points.map(p => p.pointUuid);
|
||||
const hasBothPoints = wallPoints.includes(pointA.pointUuid) && wallPoints.includes(pointB.pointUuid);
|
||||
|
||||
if (hasBothPoints) {
|
||||
removedWall = JSON.parse(JSON.stringify(wall));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
return removedWall;
|
||||
},
|
||||
|
||||
addDecal: (wallUuid, decal) => set((state) => {
|
||||
const wallToUpdate = state.walls.find(w => w.wallUuid === wallUuid);
|
||||
if (wallToUpdate) {
|
||||
wallToUpdate.decals.push(decal);
|
||||
}
|
||||
}),
|
||||
|
||||
updateDecal: (decalUuid, decal) => set((state) => {
|
||||
for (const wall of state.walls) {
|
||||
const decalToUpdate = wall.decals.find(d => d.decalUuid === decalUuid);
|
||||
if (decalToUpdate) {
|
||||
Object.assign(decalToUpdate, decal);
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
removeDecal: (decalUuid) => set((state) => {
|
||||
for (const wall of state.walls) {
|
||||
wall.decals = wall.decals.filter(d => d.decalUuid !== decalUuid);
|
||||
}
|
||||
}),
|
||||
|
||||
updateDecalPosition: (decalUuid, position) => set((state) => {
|
||||
for (const wall of state.walls) {
|
||||
const decal = wall.decals.find(d => d.decalUuid === decalUuid);
|
||||
if (decal) {
|
||||
decal.decalPosition = position;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
updateDecalRotation: (decalUuid, rotation) => set((state) => {
|
||||
for (const wall of state.walls) {
|
||||
const decal = wall.decals.find(d => d.decalUuid === decalUuid);
|
||||
if (decal) {
|
||||
decal.decalRotation = rotation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
updateDecalScale: (decalUuid, scale) => set((state) => {
|
||||
for (const wall of state.walls) {
|
||||
const decal = wall.decals.find(d => d.decalUuid === decalUuid);
|
||||
if (decal) {
|
||||
decal.decalScale = scale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
removePoint: (pointUuid) => {
|
||||
const removedWalls: Wall[] = [];
|
||||
set((state) => {
|
||||
state.walls = state.walls.filter((wall) => {
|
||||
const hasPoint = wall.points.some(p => p.pointUuid === pointUuid);
|
||||
if (hasPoint) {
|
||||
removedWalls.push(JSON.parse(JSON.stringify(wall)));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
});
|
||||
return removedWalls;
|
||||
},
|
||||
|
||||
setPosition: (pointUuid, position) => set((state) => {
|
||||
for (const wall of state.walls) {
|
||||
const point = wall.points.find(p => p.pointUuid === pointUuid);
|
||||
if (point) {
|
||||
point.position = position;
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
setLayer: (pointUuid, layer) => set((state) => {
|
||||
for (const wall of state.walls) {
|
||||
const point = wall.points.find(p => p.pointUuid === pointUuid);
|
||||
if (point) {
|
||||
point.layer = layer;
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
getWallById: (uuid) => {
|
||||
return get().walls.find(w => w.wallUuid === uuid);
|
||||
},
|
||||
|
||||
getWallByPointId: (uuid) => {
|
||||
for (const wall of get().walls) {
|
||||
if (wall.points.some(p => p.pointUuid === uuid)) {
|
||||
return wall;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
getWallByPoints: (point) => {
|
||||
for (const wall of get().walls) {
|
||||
if (((wall.points[0].pointUuid === point[0].pointUuid) || (wall.points[1].pointUuid === point[0].pointUuid)) &&
|
||||
((wall.points[0].pointUuid === point[1].pointUuid) || (wall.points[1].pointUuid === point[1].pointUuid))) {
|
||||
return wall;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
getWallPointById: (uuid) => {
|
||||
for (const wall of get().walls) {
|
||||
const point = wall.points.find(p => p.pointUuid === uuid);
|
||||
if (point) return point;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
getConnectedPoints: (uuid) => {
|
||||
const connected: Point[] = [];
|
||||
for (const wall of get().walls) {
|
||||
for (const point of wall.points) {
|
||||
if (point.pointUuid === uuid) {
|
||||
connected.push(...wall.points.filter(p => p.pointUuid !== uuid));
|
||||
}
|
||||
}
|
||||
}
|
||||
return connected;
|
||||
},
|
||||
}))
|
||||
)
|
||||
}
|
||||
|
||||
export type WallStoreType = ReturnType<typeof createWallStore>;
|
||||
@@ -1,200 +0,0 @@
|
||||
import { create } from 'zustand';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
|
||||
interface WallStore {
|
||||
walls: Wall[];
|
||||
setWalls: (walls: Wall[]) => void;
|
||||
addWall: (wall: Wall) => void;
|
||||
updateWall: (uuid: string, updated: Partial<Wall>) => void;
|
||||
removeWall: (uuid: string) => void;
|
||||
removeWallByPoints: (Points: [Point, Point]) => Wall | undefined;
|
||||
addDecal: (wallUuid: string, decal: Decal) => void;
|
||||
updateDecal: (decalUuid: string, decal: Decal) => void;
|
||||
removeDecal: (decalUuid: string) => void;
|
||||
updateDecalPosition: (decalUuid: string, position: [number, number, number]) => void;
|
||||
updateDecalRotation: (decalUuid: string, rotation: number) => void;
|
||||
updateDecalScale: (decalUuid: string, scale: number) => void;
|
||||
|
||||
removePoint: (pointUuid: string) => Wall[];
|
||||
setPosition: (pointUuid: string, position: [number, number, number]) => void;
|
||||
setLayer: (pointUuid: string, layer: number) => void;
|
||||
|
||||
getWallById: (uuid: string) => Wall | undefined;
|
||||
getWallByPointId: (uuid: string) => Wall | undefined;
|
||||
getWallByPoints: (points: Point[]) => Wall | undefined;
|
||||
getWallPointById: (uuid: string) => Point | undefined;
|
||||
getConnectedPoints: (uuid: string) => Point[];
|
||||
}
|
||||
|
||||
export const useWallStore = create<WallStore>()(
|
||||
immer((set, get) => ({
|
||||
walls: [],
|
||||
|
||||
setWalls: (walls) => set((state) => {
|
||||
state.walls = walls;
|
||||
}),
|
||||
|
||||
addWall: (wall) => set((state) => {
|
||||
state.walls.push(wall);
|
||||
}),
|
||||
|
||||
updateWall: (uuid, updated) => set((state) => {
|
||||
const wall = state.walls.find(w => w.wallUuid === uuid);
|
||||
if (wall) {
|
||||
Object.assign(wall, updated);
|
||||
}
|
||||
}),
|
||||
|
||||
removeWall: (uuid) => set((state) => {
|
||||
state.walls = state.walls.filter(w => w.wallUuid !== uuid);
|
||||
}),
|
||||
|
||||
removeWallByPoints: (points) => {
|
||||
let removedWall: Wall | undefined;
|
||||
const [pointA, pointB] = points;
|
||||
|
||||
set((state) => {
|
||||
state.walls = state.walls.filter(wall => {
|
||||
const wallPoints = wall.points.map(p => p.pointUuid);
|
||||
const hasBothPoints = wallPoints.includes(pointA.pointUuid) && wallPoints.includes(pointB.pointUuid);
|
||||
|
||||
if (hasBothPoints) {
|
||||
removedWall = JSON.parse(JSON.stringify(wall));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
return removedWall;
|
||||
},
|
||||
|
||||
addDecal: (wallUuid, decal) => set((state) => {
|
||||
const wallToUpdate = state.walls.find(w => w.wallUuid === wallUuid);
|
||||
if (wallToUpdate) {
|
||||
wallToUpdate.decals.push(decal);
|
||||
}
|
||||
}),
|
||||
|
||||
updateDecal: (decalUuid, decal) => set((state) => {
|
||||
for (const wall of state.walls) {
|
||||
const decalToUpdate = wall.decals.find(d => d.decalUuid === decalUuid);
|
||||
if (decalToUpdate) {
|
||||
Object.assign(decalToUpdate, decal);
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
removeDecal: (decalUuid) => set((state) => {
|
||||
for (const wall of state.walls) {
|
||||
wall.decals = wall.decals.filter(d => d.decalUuid !== decalUuid);
|
||||
}
|
||||
}),
|
||||
|
||||
updateDecalPosition: (decalUuid, position) => set((state) => {
|
||||
for (const wall of state.walls) {
|
||||
const decal = wall.decals.find(d => d.decalUuid === decalUuid);
|
||||
if (decal) {
|
||||
decal.decalPosition = position;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
updateDecalRotation: (decalUuid, rotation) => set((state) => {
|
||||
for (const wall of state.walls) {
|
||||
const decal = wall.decals.find(d => d.decalUuid === decalUuid);
|
||||
if (decal) {
|
||||
decal.decalRotation = rotation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
updateDecalScale: (decalUuid, scale) => set((state) => {
|
||||
for (const wall of state.walls) {
|
||||
const decal = wall.decals.find(d => d.decalUuid === decalUuid);
|
||||
if (decal) {
|
||||
decal.decalScale = scale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
removePoint: (pointUuid) => {
|
||||
const removedWalls: Wall[] = [];
|
||||
set((state) => {
|
||||
state.walls = state.walls.filter((wall) => {
|
||||
const hasPoint = wall.points.some(p => p.pointUuid === pointUuid);
|
||||
if (hasPoint) {
|
||||
removedWalls.push(JSON.parse(JSON.stringify(wall)));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
});
|
||||
return removedWalls;
|
||||
},
|
||||
|
||||
setPosition: (pointUuid, position) => set((state) => {
|
||||
for (const wall of state.walls) {
|
||||
const point = wall.points.find(p => p.pointUuid === pointUuid);
|
||||
if (point) {
|
||||
point.position = position;
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
setLayer: (pointUuid, layer) => set((state) => {
|
||||
for (const wall of state.walls) {
|
||||
const point = wall.points.find(p => p.pointUuid === pointUuid);
|
||||
if (point) {
|
||||
point.layer = layer;
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
getWallById: (uuid) => {
|
||||
return get().walls.find(w => w.wallUuid === uuid);
|
||||
},
|
||||
|
||||
getWallByPointId: (uuid) => {
|
||||
for (const wall of get().walls) {
|
||||
if (wall.points.some(p => p.pointUuid === uuid)) {
|
||||
return wall;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
getWallByPoints: (point) => {
|
||||
for (const wall of get().walls) {
|
||||
if (((wall.points[0].pointUuid === point[0].pointUuid) || (wall.points[1].pointUuid === point[0].pointUuid)) &&
|
||||
((wall.points[0].pointUuid === point[1].pointUuid) || (wall.points[1].pointUuid === point[1].pointUuid))) {
|
||||
return wall;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
getWallPointById: (uuid) => {
|
||||
for (const wall of get().walls) {
|
||||
const point = wall.points.find(p => p.pointUuid === uuid);
|
||||
if (point) return point;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
getConnectedPoints: (uuid) => {
|
||||
const connected: Point[] = [];
|
||||
for (const wall of get().walls) {
|
||||
for (const point of wall.points) {
|
||||
if (point.pointUuid === uuid) {
|
||||
connected.push(...wall.points.filter(p => p.pointUuid !== uuid));
|
||||
}
|
||||
}
|
||||
}
|
||||
return connected;
|
||||
},
|
||||
}))
|
||||
);
|
||||
74
app/src/store/builder/useZoneStore.ts
Normal file
74
app/src/store/builder/useZoneStore.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { create } from 'zustand';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
|
||||
interface ZoneStore {
|
||||
zones: Zone[];
|
||||
setZones: (zones: Zone[]) => void;
|
||||
addZone: (zone: Zone) => void;
|
||||
updateZone: (uuid: string, updated: Partial<Zone>) => void;
|
||||
removeZone: (uuid: string) => void;
|
||||
removePointFromZones: (pointUuid: string) => void;
|
||||
clearZones: () => void;
|
||||
setViewPort: (uuid: string, position: [number, number, number], target: [number, number, number]) => void;
|
||||
setColor: (uuid: string, color: string) => void;
|
||||
|
||||
getZoneById: (uuid: string) => Zone | undefined;
|
||||
}
|
||||
|
||||
export const createZoneStore = () => {
|
||||
return create<ZoneStore>()(
|
||||
immer((set, get) => ({
|
||||
zones: [],
|
||||
|
||||
setZones: (zones) => set(state => {
|
||||
state.zones = zones;
|
||||
}),
|
||||
|
||||
addZone: (zone) => set(state => {
|
||||
state.zones.push(zone);
|
||||
}),
|
||||
|
||||
updateZone: (uuid, updated) => set(state => {
|
||||
const zone = state.zones.find(z => z.zoneUuid === uuid);
|
||||
if (zone) {
|
||||
Object.assign(zone, updated);
|
||||
}
|
||||
}),
|
||||
|
||||
removeZone: (uuid) => set(state => {
|
||||
state.zones = state.zones.filter(z => z.zoneUuid !== uuid);
|
||||
}),
|
||||
|
||||
removePointFromZones: (pointUuid) => set(state => {
|
||||
for (const zone of state.zones) {
|
||||
zone.points = zone.points.filter(p => p.pointUuid !== pointUuid);
|
||||
}
|
||||
}),
|
||||
|
||||
clearZones: () => set(state => {
|
||||
state.zones = [];
|
||||
}),
|
||||
|
||||
setViewPort: (uuid, position, target) => set(state => {
|
||||
const zone = state.zones.find(z => z.zoneUuid === uuid);
|
||||
if (zone) {
|
||||
zone.viewPortPosition = position;
|
||||
zone.viewPortTarget = target;
|
||||
}
|
||||
}),
|
||||
|
||||
setColor: (uuid, color) => set(state => {
|
||||
const zone = state.zones.find(z => z.zoneUuid === uuid);
|
||||
if (zone) {
|
||||
zone.zoneColor = color;
|
||||
}
|
||||
}),
|
||||
|
||||
getZoneById: (uuid) => {
|
||||
return get().zones.find(z => z.zoneUuid === uuid);
|
||||
},
|
||||
}))
|
||||
);
|
||||
};
|
||||
|
||||
export type ZoneStoreType = ReturnType<typeof createZoneStore>;
|
||||
Reference in New Issue
Block a user