Skip to content

Commit 6d4d87c

Browse files
Refactor various components to use list comprehensions for improved readability and performance; add settings.json for tool permissions
1 parent b55d847 commit 6d4d87c

7 files changed

Lines changed: 105 additions & 100 deletions

File tree

components/Canvas.cl.jac

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -495,9 +495,7 @@ def:pub Canvas(props: dict) -> JsxElement {
495495
dup.bendY = original.bendY + dy;
496496
}
497497
} elif original.type == "freehand" {
498-
dup.points = original.points.map(lambda p: dict -> dict {
499-
return {"x": p.x + dx, "y": p.y + dy};
500-
});
498+
dup.points = [{"x": p.x + dx, "y": p.y + dy} for p in original.points];
501499
}
502500
return dup;
503501
}
@@ -544,9 +542,15 @@ def:pub Canvas(props: dict) -> JsxElement {
544542
if selectionHook.selectedElement {
545543
idx = selectionHook.selectedElement.index;
546544
element = selectionHook.selectedElement.element;
547-
newElements = [element].concat(elementsHook.elements.filter(lambda _: any, i: any -> bool {
548-
return i != idx;
549-
}));
545+
otherElements = [];
546+
bfi = 0;
547+
while bfi < elementsHook.elements.length {
548+
if bfi != idx {
549+
otherElements.push(elementsHook.elements[bfi]);
550+
}
551+
bfi = bfi + 1;
552+
}
553+
newElements = [element].concat(otherElements);
550554
elementsHook.setElements(newElements);
551555
selectionHook.clearSelection();
552556
}
@@ -1100,12 +1104,10 @@ def:pub Canvas(props: dict) -> JsxElement {
11001104
scaleY = (bh + deltaY) / bh;
11011105
if scaleX < 0.1 { scaleX = 0.1; }
11021106
if scaleY < 0.1 { scaleY = 0.1; }
1103-
newElement.points = origEl.points.map(lambda point: dict -> dict {
1104-
return {
1105-
"x": minX + (point.x - minX) * scaleX,
1106-
"y": minY + (point.y - minY) * scaleY
1107-
};
1108-
});
1107+
newElement.points = [
1108+
{"x": minX + (point.x - minX) * scaleX, "y": minY + (point.y - minY) * scaleY}
1109+
for point in origEl.points
1110+
];
11091111
}
11101112
}
11111113
}
@@ -1173,9 +1175,7 @@ def:pub Canvas(props: dict) -> JsxElement {
11731175
newElement.bendY = originalElement.bendY + multiDy;
11741176
}
11751177
} elif originalElement.type == "freehand" {
1176-
newElement.points = originalElement.points.map(lambda point: dict -> dict {
1177-
return {"x": point.x + multiDx, "y": point.y + multiDy};
1178-
});
1178+
newElement.points = [{"x": point.x + multiDx, "y": point.y + multiDy} for point in originalElement.points];
11791179
}
11801180

11811181
updates.push({"index": selectedInfo.index, "element": newElement});
@@ -1249,9 +1249,7 @@ def:pub Canvas(props: dict) -> JsxElement {
12491249
} elif element.type == "freehand" {
12501250
fhDx = pos.x - selectionHook.dragOffset.x - element.points[0].x;
12511251
fhDy = pos.y - selectionHook.dragOffset.y - element.points[0].y;
1252-
newElement.points = element.points.map(lambda point: dict -> dict {
1253-
return {"x": point.x + fhDx, "y": point.y + fhDy};
1254-
});
1252+
newElement.points = [{"x": point.x + fhDx, "y": point.y + fhDy} for point in element.points];
12551253
}
12561254

12571255
# Move connected lines/arrows along with the shape

components/layout/Sidebar.cl.jac

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -198,16 +198,16 @@ def:pub Sidebar(props: dict) -> JsxElement {
198198
{showColor and <div>
199199
<span className="sidebar-label">Stroke</span>
200200
<div className="grid grid-cols-5 gap-1.5 mt-1.5">
201-
{presetColors.map(lambda color: any -> any {
202-
isSelected = activeColor == color;
203-
return <button
201+
{[
202+
<button
204203
key={color}
205204
onClick={lambda -> None { handleColorChange(color); }}
206205
title={color}
207-
className={"w-7 h-7 rounded-full transition-all duration-150 border border-gray-200/60 " + (isSelected and "ring-2 ring-orange-500 ring-offset-1 scale-110" or "hover:scale-110")}
206+
className={"w-7 h-7 rounded-full transition-all duration-150 border border-gray-200/60 " + (activeColor == color and "ring-2 ring-orange-500 ring-offset-1 scale-110" or "hover:scale-110")}
208207
style={{"backgroundColor": color}}
209-
/>;
210-
})}
208+
/>
209+
for color in presetColors
210+
]}
211211
</div>
212212
<input
213213
type="color"
@@ -256,16 +256,16 @@ def:pub Sidebar(props: dict) -> JsxElement {
256256
{showShapeTextColor and <div>
257257
<span className="sidebar-label">Text Color</span>
258258
<div className="grid grid-cols-5 gap-1.5 mt-1.5">
259-
{presetColors.map(lambda stcColor: any -> any {
260-
stcSelected = activeShapeTextColor == stcColor;
261-
return <button
259+
{[
260+
<button
262261
key={stcColor}
263262
onClick={lambda -> None { handleShapeTextColorChange(stcColor); }}
264263
title={stcColor}
265-
className={"w-7 h-7 rounded-full transition-all duration-150 border border-gray-200/60 " + (stcSelected and "ring-2 ring-orange-500 ring-offset-1 scale-110" or "hover:scale-110")}
264+
className={"w-7 h-7 rounded-full transition-all duration-150 border border-gray-200/60 " + (activeShapeTextColor == stcColor and "ring-2 ring-orange-500 ring-offset-1 scale-110" or "hover:scale-110")}
266265
style={{"backgroundColor": stcColor}}
267-
/>;
268-
})}
266+
/>
267+
for stcColor in presetColors
268+
]}
269269
</div>
270270
<input
271271
type="color"
@@ -297,25 +297,25 @@ def:pub Sidebar(props: dict) -> JsxElement {
297297
{showLineStyle and <div>
298298
<span className="sidebar-label">Line Style</span>
299299
<div className="flex items-center gap-1 mt-1.5">
300-
{lineStyles.map(lambda style: any -> any {
301-
isActive = activeLineStyle == style.id;
302-
return <button
300+
{[
301+
<button
303302
key={style.id}
304303
onClick={lambda -> None { handleLineStyleChange(style.id); }}
305304
title={style.label}
306-
className={"flex-1 h-8 rounded-lg flex items-center justify-center transition-all duration-150 " + (isActive and "bg-orange-50 ring-1 ring-orange-200" or "bg-gray-50 hover:bg-gray-100")}
305+
className={"flex-1 h-8 rounded-lg flex items-center justify-center transition-all duration-150 " + (activeLineStyle == style.id and "bg-orange-50 ring-1 ring-orange-200" or "bg-gray-50 hover:bg-gray-100")}
307306
>
308307
<svg width="32" height="4" viewBox="0 0 32 4">
309308
<line
310309
x1="2" y1="2" x2="30" y2="2"
311-
stroke={isActive and "#ea580c" or "#9ca3af"}
310+
stroke={activeLineStyle == style.id and "#ea580c" or "#9ca3af"}
312311
strokeWidth="2"
313312
strokeLinecap="round"
314313
strokeDasharray={style.id == "dashed" and "6,4" or (style.id == "dotted" and "2,4" or "none")}
315314
/>
316315
</svg>
317-
</button>;
318-
})}
316+
</button>
317+
for style in lineStyles
318+
]}
319319
</div>
320320
</div> or None}
321321
@@ -339,34 +339,34 @@ def:pub Sidebar(props: dict) -> JsxElement {
339339
<div className="h-px bg-gray-100 mb-3"></div>
340340
<span className="sidebar-label">Font</span>
341341
<div className="flex flex-col gap-0.5 mt-1.5">
342-
{fonts.map(lambda font: any -> any {
343-
isActive = activeFontFamily == font.id;
344-
return <button
342+
{[
343+
<button
345344
key={font.id}
346345
onClick={lambda -> None { handleFontFamilyChange(font.id); }}
347346
title={font.id}
348-
className={"px-2 h-7 rounded-md flex items-center text-xs font-medium transition-all duration-150 whitespace-nowrap " + (isActive and "bg-orange-50 text-orange-700 ring-1 ring-orange-200" or "text-gray-500 hover:bg-gray-50")}
347+
className={"px-2 h-7 rounded-md flex items-center text-xs font-medium transition-all duration-150 whitespace-nowrap " + (activeFontFamily == font.id and "bg-orange-50 text-orange-700 ring-1 ring-orange-200" or "text-gray-500 hover:bg-gray-50")}
349348
style={{"fontFamily": font.id}}
350349
>
351350
{font.label}
352-
</button>;
353-
})}
351+
</button>
352+
for font in fonts
353+
]}
354354
</div>
355355
</div> or None}
356356
357357
{showFontSize and <div>
358358
<span className="sidebar-label mt-3">Size</span>
359359
<div className="grid grid-cols-3 gap-1 mt-1.5">
360-
{fontSizes.map(lambda size: any -> any {
361-
isActive = activeFontSize == size;
362-
return <button
360+
{[
361+
<button
363362
key={size}
364363
onClick={lambda -> None { handleFontSizeChange(size); }}
365-
className={"h-7 rounded-md flex items-center justify-center text-xs font-medium transition-all duration-150 " + (isActive and "bg-orange-50 text-orange-700 ring-1 ring-orange-200" or "text-gray-500 hover:bg-gray-50")}
364+
className={"h-7 rounded-md flex items-center justify-center text-xs font-medium transition-all duration-150 " + (activeFontSize == size and "bg-orange-50 text-orange-700 ring-1 ring-orange-200" or "text-gray-500 hover:bg-gray-50")}
366365
>
367366
{size}
368-
</button>;
369-
})}
367+
</button>
368+
for size in fontSizes
369+
]}
370370
</div>
371371
</div> or None}
372372
</div>;

components/layout/TopBar.cl.jac

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,19 +142,18 @@ def:pub TopBar(props: dict) -> JsxElement {
142142
</div>
143143
144144
<div className="flex items-center gap-0.5 bg-gray-50 rounded-lg px-1 py-0.5">
145-
{toolIds.map(lambda toolId: any -> any {
146-
isActive = currentTool == toolId and toolId != "image";
147-
shortcut = toolShortcuts[toolId];
148-
return <button
145+
{[
146+
<button
149147
key={toolId}
150148
onClick={lambda -> None { handleToolClick(toolId); }}
151-
title={toolLabels[toolId] + (shortcut and (" (" + shortcut + ")") or "")}
152-
className={"relative w-9 h-9 rounded-md flex flex-col items-center justify-center gap-0 transition-all duration-150 " + (isActive and "bg-white text-orange-600 shadow-sm" or "text-gray-400 hover:bg-white/60 hover:text-gray-600")}
149+
title={toolLabels[toolId] + (toolShortcuts[toolId] and (" (" + toolShortcuts[toolId] + ")") or "")}
150+
className={"relative w-9 h-9 rounded-md flex flex-col items-center justify-center gap-0 transition-all duration-150 " + (currentTool == toolId and toolId != "image" and "bg-white text-orange-600 shadow-sm" or "text-gray-400 hover:bg-white/60 hover:text-gray-600")}
153151
>
154-
<ToolIcon toolId={toolId} size={17} color={isActive and "#ea580c" or "currentColor"} />
155-
{shortcut and <span className={"text-[7px] leading-none font-medium mt-px " + (isActive and "text-orange-400" or "text-gray-300")}>{shortcut}</span> or None}
156-
</button>;
157-
})}
152+
<ToolIcon toolId={toolId} size={17} color={currentTool == toolId and toolId != "image" and "#ea580c" or "currentColor"} />
153+
{toolShortcuts[toolId] and <span className={"text-[7px] leading-none font-medium mt-px " + (currentTool == toolId and toolId != "image" and "text-orange-400" or "text-gray-300")}>{toolShortcuts[toolId]}</span> or None}
154+
</button>
155+
for toolId in toolIds
156+
]}
158157
</div>
159158
160159
<div className="min-w-[120px] flex justify-end">

hooks/useCanvas.cl.jac

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,13 @@ def:pub useCanvas() -> dict {
8686
drawGroupSelectionBox(ctx, groupEls);
8787
} else {
8888
# Draw individual selection boxes
89-
selectedElements.forEach(lambda sel: dict -> None {
90-
if sel.element {
91-
drawSelectionBox(ctx, sel.element);
89+
selBoxIdx = 0;
90+
while selBoxIdx < selectedElements.length {
91+
if selectedElements[selBoxIdx].element {
92+
drawSelectionBox(ctx, selectedElements[selBoxIdx].element);
9293
}
93-
});
94+
selBoxIdx = selBoxIdx + 1;
95+
}
9496
}
9597
}
9698

hooks/useElements.cl.jac

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,14 @@ def:pub useElements() -> dict {
1111
def setElementsInternal(newElements: list) -> None {
1212
elements = newElements;
1313
# Strip non-serializable imageObj before saving to localStorage
14-
toStore = newElements.map(lambda el: any -> any {
15-
if el.type == "image" and el.imageObj {
16-
return {
17-
"type": el.type,
18-
"x": el.x,
19-
"y": el.y,
20-
"width": el.width,
21-
"height": el.height,
22-
"src": el.src,
23-
"opacity": el.opacity,
24-
"groupId": el.groupId
25-
};
26-
}
27-
return el;
28-
});
14+
toStore = [
15+
el.type == "image" and el.imageObj and {
16+
"type": el.type, "x": el.x, "y": el.y,
17+
"width": el.width, "height": el.height,
18+
"src": el.src, "opacity": el.opacity, "groupId": el.groupId
19+
} or el
20+
for el in newElements
21+
];
2922
localStorage.setItem(STORAGE_KEY, JSON.stringify(toStore));
3023
}
3124

@@ -106,9 +99,14 @@ def:pub useElements() -> dict {
10699
}
107100

108101
def removeElement(index: int) -> None {
109-
newElements = elements.filter(lambda _: any, i: any -> bool {
110-
return i != index;
111-
});
102+
newElements = [];
103+
ri = 0;
104+
while ri < elements.length {
105+
if ri != index {
106+
newElements.push(elements[ri]);
107+
}
108+
ri = ri + 1;
109+
}
112110
setElementsWithHistory(newElements);
113111
}
114112

@@ -119,9 +117,14 @@ def:pub useElements() -> dict {
119117
indexSet[indices[i]] = True;
120118
i = i + 1;
121119
}
122-
newElements = elements.filter(lambda _: any, i: any -> bool {
123-
return not indexSet[i];
124-
});
120+
newElements = [];
121+
rmi = 0;
122+
while rmi < elements.length {
123+
if not indexSet[rmi] {
124+
newElements.push(elements[rmi]);
125+
}
126+
rmi = rmi + 1;
127+
}
125128
setElementsWithHistory(newElements);
126129
}
127130

hooks/useSelection.cl.jac

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,7 @@ def:pub useSelection() -> dict {
105105
}
106106

107107
def removeFromSelection(index: int) -> None {
108-
newList = selectedElements.filter(lambda sel: dict -> bool {
109-
return sel.index != index;
110-
});
108+
newList = [sel for sel in selectedElements if sel.index != index];
111109
selectedElements = newList;
112110
if newList.length == 1 {
113111
selectedElement = newList[0];

services/canvas.cl.jac

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,11 @@ def:pub drawTextElement(ctx: any, element: dict) -> None {
7373
ctx.shadowOffsetY = 1;
7474

7575
lines = element.text.split(String.fromCharCode(10));
76-
lines.forEach(lambda line: any, index: any -> None {
77-
ctx.fillText(line, element.x, element.y + (index * element.fontSize * 1.2));
78-
});
76+
lineIdx = 0;
77+
while lineIdx < lines.length {
78+
ctx.fillText(lines[lineIdx], element.x, element.y + (lineIdx * element.fontSize * 1.2));
79+
lineIdx = lineIdx + 1;
80+
}
7981
ctx.restore();
8082
}
8183

@@ -553,20 +555,23 @@ def:pub getElementBounds(ctx: any, element: dict) -> dict {
553555
fMaxX = element.points[0].x;
554556
fMaxY = element.points[0].y;
555557

556-
element.points.forEach(lambda point: dict -> None {
557-
if point.x < fMinX {
558-
fMinX = point.x;
558+
fpi = 0;
559+
while fpi < element.points.length {
560+
fPoint = element.points[fpi];
561+
if fPoint.x < fMinX {
562+
fMinX = fPoint.x;
559563
}
560-
if point.y < fMinY {
561-
fMinY = point.y;
564+
if fPoint.y < fMinY {
565+
fMinY = fPoint.y;
562566
}
563-
if point.x > fMaxX {
564-
fMaxX = point.x;
567+
if fPoint.x > fMaxX {
568+
fMaxX = fPoint.x;
565569
}
566-
if point.y > fMaxY {
567-
fMaxY = point.y;
570+
if fPoint.y > fMaxY {
571+
fMaxY = fPoint.y;
568572
}
569-
});
573+
fpi = fpi + 1;
574+
}
570575

571576
return {
572577
"x": fMinX - padding,

0 commit comments

Comments
 (0)