Skip to content

Commit c9a8220

Browse files
committed
fix: save and load layers from local storage, add toasts lib
1 parent 798a370 commit c9a8220

File tree

16 files changed

+93
-25
lines changed

16 files changed

+93
-25
lines changed

package-lock.json

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"jspdf": "^3.0.1",
2525
"react": "^18.3.1",
2626
"react-dom": "^18.3.1",
27+
"react-toastify": "^11.0.5",
2728
"svg-parser": "^2.0.4",
2829
"svg2pdf.js": "^2.5.0",
2930
"teenyicons": "^0.4.1",

src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import './App.css';
2+
import {ToastContainer} from 'react-toastify';
23
import {Toolbar} from './components/Toolbar.tsx';
34

45
function App() {
56
return (
67
<div className="overflow-y-scroll h-lvh pb-12 w-80" style={{ scrollbarWidth: 'none' }}>
78
<Toolbar />
9+
<ToastContainer position="bottom-right" theme="light" />
810
</div>
911
);
1012
}

src/components/LayerManager.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type {FC, MouseEvent} from 'react';
22
import type {Layer} from '../App.types.ts';
33
import {getNewLayer} from '../helpers/get-new-layer.ts';
4-
import {getEntities, getLayers, getSelectedEntities, setEntities, setSelectedEntityIds,} from '../state.ts';
4+
import {getActiveLayerId, getEntities, getLayers, getSelectedEntities, setEntities, setSelectedEntityIds,} from '../state.ts';
55
import {Button} from './Button';
66
import {IconName} from './Icon/Icon.tsx';
77

@@ -45,6 +45,9 @@ export const LayerManager: FC<LayerManagerProps> = ({
4545
const entitiesNotOnLayer = getEntities().filter((entity) => entity.layerId !== layerId);
4646
setEntities(entitiesNotOnLayer);
4747
setLayers(getLayers().filter((layer) => layer.id !== layerId));
48+
if (getActiveLayerId() === layerId) {
49+
setActiveLayerId(getLayers()[0].id);
50+
}
4851
};
4952

5053
const handleShowHideLayer = (evt: MouseEvent, layerId: string): void => {
@@ -71,6 +74,7 @@ export const LayerManager: FC<LayerManagerProps> = ({
7174
evt.stopPropagation();
7275
const newLayer: Layer = getNewLayer();
7376
setLayers([...getLayers(), newLayer]);
77+
setActiveLayerId(newLayer.id);
7478
};
7579

7680
return (

src/entities/ArcEntity.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ export class ArcEntity implements Entity {
239239
throw new Error('Invalid Entity type in JSON');
240240
}
241241

242+
if (!jsonEntity.shapeData) {
243+
throw new Error('Invalid JSON entity of type Arc: missing shapeData');
244+
}
245+
242246
const center = new Point(
243247
jsonEntity.shapeData.center.x,
244248
jsonEntity.shapeData.center.y,

src/entities/ArrowHeadEntity.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ export class ArrowHeadEntity implements Entity {
140140
public static async fromJson(
141141
jsonEntity: JsonEntity<ArrowHeadJsonData>
142142
): Promise<ArrowHeadEntity> {
143+
if (!jsonEntity.shapeData) {
144+
throw new Error('Invalid JSON entity of type Arrow: missing shapeData');
145+
}
143146
const p1 = new Point(jsonEntity.shapeData.p1.x, jsonEntity.shapeData.p1.y);
144147
const p2 = new Point(jsonEntity.shapeData.p2.x, jsonEntity.shapeData.p2.y);
145148
const p3 = new Point(jsonEntity.shapeData.p3.x, jsonEntity.shapeData.p3.y);

src/entities/CircleEntity.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ export class CircleEntity implements Entity {
205205
public static async fromJson(
206206
jsonEntity: JsonEntity<CircleJsonData>,
207207
): Promise<CircleEntity> {
208+
if (!jsonEntity.shapeData) {
209+
throw new Error('Invalid JSON entity of type Circle: missing shapeData');
210+
}
208211
const center = new Point(
209212
jsonEntity.shapeData.center.x,
210213
jsonEntity.shapeData.center.y,

src/entities/ImageEntity.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ export class ImageEntity implements Entity {
221221
}
222222

223223
public static async fromJson(jsonEntity: JsonEntity<ImageJsonData>): Promise<ImageEntity> {
224+
if (!jsonEntity.shapeData) {
225+
throw new Error('Invalid JSON entity of type Image: missing shapeData');
226+
}
224227
const rectangle = new Polygon(
225228
jsonEntity.shapeData.points.map((point) => new Point(point.x, point.y))
226229
);

src/entities/LineEntity.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ export class LineEntity implements Entity {
186186
}
187187

188188
public static async fromJson(jsonEntity: JsonEntity<LineJsonData>): Promise<LineEntity> {
189+
if (!jsonEntity.shapeData) {
190+
throw new Error('Invalid JSON entity of type Line: missing shapeData');
191+
}
189192
const startPoint = new Point(
190193
jsonEntity.shapeData.startPoint.x,
191194
jsonEntity.shapeData.startPoint.y

src/entities/MeasurementEntity.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import {Box, Line, Point, Segment, Vector} from '@flatten-js/core';
22
import {minBy, round} from 'es-toolkit';
33
import {max, min} from 'es-toolkit/compat';
44
import {
5-
ARROW_HEAD_LENGTH,
6-
ARROW_HEAD_WIDTH,
7-
MEASUREMENT_DECIMAL_PLACES,
8-
MEASUREMENT_EXTENSION_LENGTH,
9-
MEASUREMENT_FONT_SIZE,
10-
MEASUREMENT_LABEL_OFFSET,
11-
MEASUREMENT_ORIGIN_MARGIN,
12-
TO_RADIANS,
5+
ARROW_HEAD_LENGTH,
6+
ARROW_HEAD_WIDTH,
7+
MEASUREMENT_DECIMAL_PLACES,
8+
MEASUREMENT_EXTENSION_LENGTH,
9+
MEASUREMENT_FONT_SIZE,
10+
MEASUREMENT_LABEL_OFFSET,
11+
MEASUREMENT_ORIGIN_MARGIN,
12+
TO_RADIANS,
1313
} from '../App.consts';
1414
import type {Shape, SnapPoint} from '../App.types';
1515
import type {DrawController} from '../drawControllers/DrawController';
@@ -381,6 +381,9 @@ export class MeasurementEntity implements Entity {
381381
public static async fromJson(
382382
jsonEntity: JsonEntity<MeasurementJsonData>
383383
): Promise<MeasurementEntity> {
384+
if (!jsonEntity.shapeData) {
385+
throw new Error('Invalid JSON entity of type Measurement: missing shapeData');
386+
}
384387
const startPoint = new Point(
385388
jsonEntity.shapeData.startPoint.x,
386389
jsonEntity.shapeData.startPoint.y

0 commit comments

Comments
 (0)