Compare commits
6 Commits
pierremtb/
...
achalmers/
Author | SHA1 | Date | |
---|---|---|---|
bdc9b7267b | |||
b54a17a4fa | |||
956f00c5a1 | |||
c585efa024 | |||
a37d395b76 | |||
548eac57af |
10
.github/workflows/playwright.yml
vendored
10
.github/workflows/playwright.yml
vendored
@ -33,8 +33,18 @@ jobs:
|
||||
rust:
|
||||
- 'src/wasm-lib/**'
|
||||
|
||||
<<<<<<< HEAD
|
||||
playwright-chrome:
|
||||
timeout-minutes: ${{ matrix.os == 'macos-14' && 60 || 40 }}
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
playwright-ubuntu:
|
||||
timeout-minutes: 30
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
=======
|
||||
playwright-ubuntu:
|
||||
timeout-minutes: 30
|
||||
runs-on: ubuntu-latest
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
@ -217149,8 +217149,8 @@
|
||||
},
|
||||
{
|
||||
"name": "tangentialArc",
|
||||
"summary": "Starting at the current sketch's origin, draw a curved line segment along",
|
||||
"description": "some part of an imaginary circle of the specified radius.\nThe arc is constructed such that the last line segment is placed tangent to the imaginary circle of the specified radius. The resulting arc is the segment of the imaginary circle from that tangent point for 'offset' degrees along the imaginary circle.",
|
||||
"summary": "Draw a curved line segment along some part of an imaginary circle of the specified radius.",
|
||||
"description": "If `relative` is true, the curve starts at the end of the previous path segment (i.e. the location of the \"pen\" which draws these lines). If `relative` is false, starts from the current sketch's origin.\nThe arc is constructed such that the last line segment is placed tangent to the imaginary circle of the specified radius. The resulting arc is the segment of the imaginary circle from that tangent point for 'offset' degrees along the imaginary circle.",
|
||||
"tags": [],
|
||||
"args": [
|
||||
{
|
||||
@ -217177,16 +217177,6 @@
|
||||
"format": "double"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "A point where the arc should end. Must lie in the same plane as the current path pen position. Must not be colinear with current path pen position.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"maxItems": 2,
|
||||
"minItems": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -223895,6 +223885,14 @@
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "relative",
|
||||
"type": "bool",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "sketch_group",
|
||||
"type": "SketchGroup",
|
||||
@ -230575,7 +230573,7 @@
|
||||
"unpublished": false,
|
||||
"deprecated": false,
|
||||
"examples": [
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle: 60, length: 10 }, %)\n |> tangentialArcTo([15, 15], %)\n |> line([10, -15], %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
"const exampleSketch = startSketchOn('XZ')\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle: 60, length: 10 }, %)\n |> tangentialArcTo([15, 15], false, %)\n |> line([10, -15], %)\n |> close(%)\n\nconst example = extrude(10, exampleSketch)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -1,12 +1,12 @@
|
||||
---
|
||||
title: "tangentialArc"
|
||||
excerpt: "Starting at the current sketch's origin, draw a curved line segment along"
|
||||
excerpt: "Draw a curved line segment along some part of an imaginary circle of the specified radius."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Starting at the current sketch's origin, draw a curved line segment along
|
||||
Draw a curved line segment along some part of an imaginary circle of the specified radius.
|
||||
|
||||
some part of an imaginary circle of the specified radius.
|
||||
If `relative` is true, the curve starts at the end of the previous path segment (i.e. the location of the "pen" which draws these lines). If `relative` is false, starts from the current sketch's origin.
|
||||
The arc is constructed such that the last line segment is placed tangent to the imaginary circle of the specified radius. The resulting arc is the segment of the imaginary circle from that tangent point for 'offset' degrees along the imaginary circle.
|
||||
|
||||
```js
|
||||
@ -37,8 +37,7 @@ const example = extrude(10, exampleSketch)
|
||||
offset: number,
|
||||
// Radius of the arc. Not to be confused with Raiders of the Lost Ark.
|
||||
radius: number,
|
||||
} |
|
||||
[number, number]
|
||||
}
|
||||
```
|
||||
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
|
||||
```js
|
||||
|
@ -9,7 +9,7 @@ Starting at the current sketch's origin, draw a curved line segment along
|
||||
some part of an imaginary circle until it reaches the desired (x, y) coordinates.
|
||||
|
||||
```js
|
||||
tangentialArcTo(to: [number], sketch_group: SketchGroup, tag?: TagDeclarator) -> SketchGroup
|
||||
tangentialArcTo(to: [number], relative: bool, sketch_group: SketchGroup, tag?: TagDeclarator) -> SketchGroup
|
||||
```
|
||||
|
||||
### Examples
|
||||
@ -18,7 +18,7 @@ tangentialArcTo(to: [number], sketch_group: SketchGroup, tag?: TagDeclarator) ->
|
||||
const exampleSketch = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> angledLine({ angle: 60, length: 10 }, %)
|
||||
|> tangentialArcTo([15, 15], %)
|
||||
|> tangentialArcTo([15, 15], false, %)
|
||||
|> line([10, -15], %)
|
||||
|> close(%)
|
||||
|
||||
@ -30,6 +30,7 @@ const example = extrude(10, exampleSketch)
|
||||
### Arguments
|
||||
|
||||
* `to`: `[number]` (REQUIRED)
|
||||
* `relative`: `bool` (REQUIRED)
|
||||
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths. (REQUIRED)
|
||||
```js
|
||||
{
|
||||
|
@ -763,7 +763,7 @@ test.describe('Editor tests', () => {
|
||||
`const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([4.61, -14.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -5.38], %)
|
||||
|> tangentialArcTo([24.95, -5.38], false, %)
|
||||
|> close(%)`
|
||||
)
|
||||
})
|
||||
@ -812,7 +812,7 @@ test.describe('Editor tests', () => {
|
||||
|
||||
// expect the code to have changed
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`const sketch001 = startSketchOn('XZ') |> startProfileAt([4.61, -14.01], %) |> line([12.73, -0.09], %) |> tangentialArcTo([24.95, -5.38], %) |> close(%)const extrude001 = extrude(5, sketch001)`
|
||||
`const sketch001 = startSketchOn('XZ') |> startProfileAt([4.61, -14.01], %) |> line([12.73, -0.09], %) |> tangentialArcTo([24.95, -5.38], false, %) |> close(%)const extrude001 = extrude(5, sketch001)`
|
||||
)
|
||||
|
||||
// Now hit undo
|
||||
@ -825,7 +825,7 @@ test.describe('Editor tests', () => {
|
||||
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([4.61, -14.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -5.38], %)
|
||||
|> tangentialArcTo([24.95, -5.38], false, %)
|
||||
|> close(%)`)
|
||||
})
|
||||
|
||||
@ -837,7 +837,7 @@ test.describe('Editor tests', () => {
|
||||
`const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([4.61, -10.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -0.38], %)
|
||||
|> tangentialArcTo([24.95, -5.38], false, %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)`
|
||||
)
|
||||
@ -928,7 +928,7 @@ test.describe('Editor tests', () => {
|
||||
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([7.12, -12.68], %)
|
||||
|> line([15.39, -2.78], %)
|
||||
|> tangentialArcTo([27.6, -3.05], %)
|
||||
|> tangentialArcTo([27.6, -3.05], false, %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)
|
||||
`)
|
||||
@ -942,7 +942,7 @@ test.describe('Editor tests', () => {
|
||||
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([7.12, -12.68], %)
|
||||
|> line([15.39, -2.78], %)
|
||||
|> tangentialArcTo([24.95, -0.38], %)
|
||||
|> tangentialArcTo([24.95, -0.38], false, %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)`)
|
||||
|
||||
@ -955,7 +955,7 @@ test.describe('Editor tests', () => {
|
||||
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([7.12, -12.68], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -0.38], %)
|
||||
|> tangentialArcTo([24.95, -0.38], false, %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)
|
||||
`)
|
||||
@ -970,7 +970,7 @@ test.describe('Editor tests', () => {
|
||||
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([4.61, -10.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -0.38], %)
|
||||
|> tangentialArcTo([24.95, -0.38], false, %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)`)
|
||||
})
|
||||
|
@ -61,7 +61,7 @@ test.describe('Sketch tests', () => {
|
||||
const part002 = startSketchOn('-XZ')
|
||||
${startProfileAt3}
|
||||
|> xLine(width / 4, %)
|
||||
|> tangentialArcTo([width / 2, 0], %)
|
||||
|> tangentialArcTo([width / 2, 0], false, %)
|
||||
|> xLine(-width / 4 + wireRadius, %)
|
||||
|> yLine(wireOffset, %)
|
||||
|> arc({
|
||||
@ -115,7 +115,7 @@ test.describe('Sketch tests', () => {
|
||||
`const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([4.61, -14.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -5.38], %)`
|
||||
|> tangentialArcTo([24.95, -5.38], false, %)`
|
||||
)
|
||||
})
|
||||
|
||||
@ -125,7 +125,7 @@ test.describe('Sketch tests', () => {
|
||||
|
||||
await expect(async () => {
|
||||
await page.mouse.click(700, 200)
|
||||
await page.getByText('tangentialArcTo([24.95, -5.38], %)').click()
|
||||
await page.getByText('tangentialArcTo([24.95, -5.38], false, %)').click()
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Edit Sketch' })
|
||||
).toBeEnabled({ timeout: 1000 })
|
||||
@ -134,7 +134,7 @@ test.describe('Sketch tests', () => {
|
||||
|
||||
await page.waitForTimeout(600) // wait for animation
|
||||
|
||||
await page.getByText('tangentialArcTo([24.95, -5.38], %)').click()
|
||||
await page.getByText('tangentialArcTo([24.95, -5.38], false, %)').click()
|
||||
await page.keyboard.press('End')
|
||||
await page.keyboard.down('Shift')
|
||||
await page.keyboard.press('ArrowUp')
|
||||
@ -193,7 +193,7 @@ test.describe('Sketch tests', () => {
|
||||
`const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([4.61, -14.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -5.38], %)
|
||||
|> tangentialArcTo([24.95, -5.38], false, %)
|
||||
|> close(%)`
|
||||
)
|
||||
})
|
||||
@ -235,7 +235,7 @@ test.describe('Sketch tests', () => {
|
||||
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([4.61, -14.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -5.38], %)
|
||||
|> tangentialArcTo([24.95, -5.38], false, %)
|
||||
|> close(%)`)
|
||||
} else {
|
||||
// Ensure we don't see the code.
|
||||
@ -312,7 +312,7 @@ test.describe('Sketch tests', () => {
|
||||
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([6.44, -12.07], %)
|
||||
|> line([14.72, 1.97], %)
|
||||
|> tangentialArcTo([24.95, -5.38], %)
|
||||
|> tangentialArcTo([24.95, -5.38], false, %)
|
||||
|> line([1.97, 2.06], %)
|
||||
|> close(%)`)
|
||||
}
|
||||
@ -354,7 +354,7 @@ test.describe('Sketch tests', () => {
|
||||
`const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([4.61, -10.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -0.38], %)
|
||||
|> tangentialArcTo([24.95, -0.38], false, %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)`
|
||||
)
|
||||
@ -441,7 +441,7 @@ test.describe('Sketch tests', () => {
|
||||
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([7.12, -12.68], %)
|
||||
|> line([15.39, -2.78], %)
|
||||
|> tangentialArcTo([27.6, -3.05], %)
|
||||
|> tangentialArcTo([27.6, -3.05], false, %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)
|
||||
`)
|
||||
@ -457,7 +457,7 @@ test.describe('Sketch tests', () => {
|
||||
`const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([4.61, -14.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -5.38], %)
|
||||
|> tangentialArcTo([24.95, -5.38], false, %)
|
||||
|> close(%)
|
||||
|> revolve({ axis: "X",}, %)`
|
||||
)
|
||||
@ -543,7 +543,7 @@ test.describe('Sketch tests', () => {
|
||||
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([6.44, -12.07], %)
|
||||
|> line([14.72, 1.97], %)
|
||||
|> tangentialArcTo([24.95, -5.38], %)
|
||||
|> tangentialArcTo([24.95, -5.38], false, %)
|
||||
|> line([1.97, 2.06], %)
|
||||
|> close(%)
|
||||
|> revolve({ axis: "X" }, %)`)
|
||||
|
@ -594,7 +594,7 @@ test.describe(
|
||||
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
||||
|
||||
code += `
|
||||
|> tangentialArcTo([21.7, -2.44], %)`
|
||||
|> tangentialArcTo([21.7, -2.44], false, %)`
|
||||
await expect(u.codeLocator).toHaveText(code)
|
||||
|
||||
// click tangential arc tool again to unequip it
|
||||
@ -697,7 +697,7 @@ test.describe(
|
||||
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
||||
|
||||
code += `
|
||||
|> tangentialArcTo([551.2, -62.01], %)`
|
||||
|> tangentialArcTo([551.2, -62.01], false, %)`
|
||||
await expect(u.codeLocator).toHaveText(code)
|
||||
|
||||
await page
|
||||
|
@ -84,7 +84,7 @@ export const TEST_CODE_GIZMO = `const part001 = startSketchOn('XZ')
|
||||
intersectTag: a,
|
||||
offset: 0
|
||||
}, %)
|
||||
|> tangentialArcTo([13.14 + 0, 13.14], %)
|
||||
|> tangentialArcTo([13.14 + 0, 13.14], false, %)
|
||||
|> close(%)
|
||||
|> extrude(5 + 7, %)
|
||||
`
|
||||
|
@ -314,6 +314,7 @@ export function normaliseKclNumbers(code: string, ignoreZero = true): string {
|
||||
return replaceNumbers(code)
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
export async function getUtils(page: Page, test_?: typeof test) {
|
||||
if (!test) {
|
||||
console.warn(
|
||||
@ -321,6 +322,11 @@ export async function getUtils(page: Page, test_?: typeof test) {
|
||||
)
|
||||
}
|
||||
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
export async function getUtils(page: Page) {
|
||||
=======
|
||||
export async function getUtils(page: Page) {
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
// Chrome devtools protocol session only works in Chromium
|
||||
const browserType = page.context().browser()?.browserType().name()
|
||||
const cdpSession =
|
||||
|
@ -200,7 +200,7 @@ test.describe('Testing segment overlays', () => {
|
||||
intersectTag: a,
|
||||
offset: 9
|
||||
}, %)
|
||||
|> tangentialArcTo([5 + 3.14 + 13, 20 + 3.14], %)
|
||||
|> tangentialArcTo([5 + 3.14 + 13, 20 + 3.14], false, %)
|
||||
`
|
||||
)
|
||||
})
|
||||
@ -438,7 +438,7 @@ const part001 = startSketchOn('XZ')
|
||||
intersectTag: a,
|
||||
offset: 9
|
||||
}, %)
|
||||
|> tangentialArcTo([3.14 + 13, 3.14], %)
|
||||
|> tangentialArcTo([3.14 + 13, 3.14], false, %)
|
||||
`
|
||||
)
|
||||
localStorage.setItem('disableAxis', 'true')
|
||||
@ -566,7 +566,7 @@ const part001 = startSketchOn('XZ')
|
||||
intersectTag: a,
|
||||
offset: 9
|
||||
}, %)
|
||||
|> tangentialArcTo([3.14 + 13, 1.14], %)
|
||||
|> tangentialArcTo([3.14 + 13, 1.14], false, %)
|
||||
`
|
||||
)
|
||||
localStorage.setItem('disableAxis', 'true')
|
||||
@ -722,7 +722,7 @@ const part001 = startSketchOn('XZ')
|
||||
intersectTag: a,
|
||||
offset: 9
|
||||
}, %)
|
||||
|> tangentialArcTo([3.14 + 13, -3.14], %)
|
||||
|> tangentialArcTo([3.14 + 13, -3.14], false, %)
|
||||
`
|
||||
)
|
||||
localStorage.setItem('disableAxis', 'true')
|
||||
@ -755,9 +755,10 @@ const part001 = startSketchOn('XZ')
|
||||
await clickConstrained({
|
||||
hoverPos: { x: tangentialArcTo.x, y: tangentialArcTo.y },
|
||||
constraintType: 'xAbsolute',
|
||||
expectBeforeUnconstrained: 'tangentialArcTo([3.14 + 13, -3.14], %)',
|
||||
expectAfterUnconstrained: 'tangentialArcTo([16.14, -3.14], %)',
|
||||
expectFinal: 'tangentialArcTo([xAbs001, -3.14], %)',
|
||||
expectBeforeUnconstrained:
|
||||
'tangentialArcTo([3.14 + 13, -3.14], false, %)',
|
||||
expectAfterUnconstrained: 'tangentialArcTo([16.14, -3.14], false, %)',
|
||||
expectFinal: 'tangentialArcTo([xAbs001, -3.14], false, %)',
|
||||
ang: ang + 180,
|
||||
steps: 6,
|
||||
locator: '[data-overlay-toolbar-index="12"]',
|
||||
@ -766,9 +767,11 @@ const part001 = startSketchOn('XZ')
|
||||
await clickUnconstrained({
|
||||
hoverPos: { x: tangentialArcTo.x, y: tangentialArcTo.y },
|
||||
constraintType: 'yAbsolute',
|
||||
expectBeforeUnconstrained: 'tangentialArcTo([xAbs001, -3.14], %)',
|
||||
expectAfterUnconstrained: 'tangentialArcTo([xAbs001, yAbs001], %)',
|
||||
expectFinal: 'tangentialArcTo([xAbs001, -3.14], %)',
|
||||
expectBeforeUnconstrained:
|
||||
'tangentialArcTo([xAbs001, -3.14], false, %)',
|
||||
expectAfterUnconstrained:
|
||||
'tangentialArcTo([xAbs001, yAbs001], false, %)',
|
||||
expectFinal: 'tangentialArcTo([xAbs001, -3.14], false, %)',
|
||||
ang: ang + 180,
|
||||
steps: 10,
|
||||
locator: '[data-overlay-toolbar-index="12"]',
|
||||
@ -835,7 +838,7 @@ const part001 = startSketchOn('XZ')
|
||||
intersectTag: a,
|
||||
offset: 9
|
||||
}, %)
|
||||
|> tangentialArcTo([3.14 + 13, 1.14], %)
|
||||
|> tangentialArcTo([3.14 + 13, 1.14], false, %)
|
||||
`
|
||||
)
|
||||
localStorage.setItem('disableAxis', 'true')
|
||||
@ -866,7 +869,7 @@ const part001 = startSketchOn('XZ')
|
||||
let ang = await u.getAngle(`[data-overlay-index="${12}"]`)
|
||||
await deleteSegmentSequence({
|
||||
hoverPos: { x: segmentToDelete.x, y: segmentToDelete.y },
|
||||
codeToBeDeleted: 'tangentialArcTo([3.14 + 13, 1.14], %)',
|
||||
codeToBeDeleted: 'tangentialArcTo([3.14 + 13, 1.14], false, %)',
|
||||
stdLibFnName: 'tangentialArcTo',
|
||||
ang: ang + 180,
|
||||
steps: 6,
|
||||
|
@ -479,7 +479,7 @@ const sketch002 = startSketchOn(launderExtrudeThroughVar, seg02)
|
||||
intersectTag: a,
|
||||
offset: 0
|
||||
}, %)
|
||||
|> tangentialArcTo([13.14 + 0, 13.14], %)
|
||||
|> tangentialArcTo([13.14 + 0, 13.14], false, %)
|
||||
|> close(%)
|
||||
|> extrude(5 + 7, %)
|
||||
`
|
||||
@ -683,7 +683,7 @@ const extrude001 = extrude(10, sketch001)`
|
||||
},
|
||||
{
|
||||
pos: [1107, 161],
|
||||
expectedCode: 'tangentialArcTo([167.95, -28.85], %)',
|
||||
expectedCode: 'tangentialArcTo([167.95, -28.85], false, %)',
|
||||
},
|
||||
] as const
|
||||
await page.addInitScript(
|
||||
|
@ -77,7 +77,17 @@ test.describe('Testing settings', () => {
|
||||
exact: true,
|
||||
})
|
||||
const inputLocator = page.locator('input[name="modeling-showDebugPanel"]')
|
||||
<<<<<<< HEAD
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
// Open the settings modal with the browser keyboard shortcut
|
||||
await page.keyboard.press('Meta+Shift+,')
|
||||
=======
|
||||
|
||||
// Open the settings modal with the browser keyboard shortcut
|
||||
await page.keyboard.press('Meta+Shift+,')
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
|
||||
<<<<<<< HEAD
|
||||
// Open the settings modal with the browser keyboard shortcut
|
||||
await page.keyboard.press('ControlOrMeta+Shift+,')
|
||||
|
||||
@ -128,7 +138,58 @@ test.describe('Testing settings', () => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await u.waitForAuthSkipAppStart()
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'Settings', exact: true })
|
||||
).toBeVisible()
|
||||
await page
|
||||
.locator('select[name="app-theme"]')
|
||||
.selectOption({ value: 'light' })
|
||||
|
||||
// Verify the toast appeared
|
||||
await expect(
|
||||
page.getByText(`Set theme to "light" for this project`)
|
||||
).toBeVisible()
|
||||
// Check that the theme changed
|
||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||
|
||||
// Check that the user setting was not changed
|
||||
await page.getByRole('radio', { name: 'User' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('dark')
|
||||
|
||||
// Roll back to default "system" theme
|
||||
await page
|
||||
.getByText(
|
||||
'themeRoll back themeRoll back to match defaultThe overall appearance of the appl'
|
||||
)
|
||||
.hover()
|
||||
await page
|
||||
.getByRole('button', {
|
||||
name: 'Roll back theme',
|
||||
})
|
||||
.click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
|
||||
// Check that the project setting did not change
|
||||
await page.getByRole('radio', { name: 'Project' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
|
||||
})
|
||||
|
||||
test('Project settings can be opened with keybinding from the editor', async ({
|
||||
page,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await page
|
||||
.getByRole('button', { name: 'Start Sketch' })
|
||||
.waitFor({ state: 'visible' })
|
||||
=======
|
||||
await expect(headingLocator).toBeVisible()
|
||||
await page.locator('#showDebugPanel').getByText('OffOn').click()
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
|
||||
<<<<<<< HEAD
|
||||
await test.step('Open keybindings settings', async () => {
|
||||
// Open the settings modal with the browser keyboard shortcut
|
||||
await page.keyboard.press('ControlOrMeta+Shift+,')
|
||||
@ -141,7 +202,31 @@ test.describe('Testing settings', () => {
|
||||
// Go to the hotkey for Command Palette.
|
||||
const commandPalette = page.getByText('Toggle Command Palette')
|
||||
await commandPalette.scrollIntoViewIfNeeded()
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
// Put the cursor in the editor
|
||||
await page.locator('.cm-content').click()
|
||||
|
||||
// Open the settings modal with the browser keyboard shortcut
|
||||
await page.keyboard.press('Meta+Shift+,')
|
||||
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'Settings', exact: true })
|
||||
).toBeVisible()
|
||||
await page
|
||||
.locator('select[name="app-theme"]')
|
||||
.selectOption({ value: 'light' })
|
||||
=======
|
||||
// Close it and open again with keyboard shortcut, while KCL editor is focused
|
||||
// Put the cursor in the editor
|
||||
await test.step('Open settings with keyboard shortcut', async () => {
|
||||
await page.getByTestId('settings-close-button').click()
|
||||
await page.locator('.cm-content').click()
|
||||
await page.keyboard.press('Meta+Shift+,')
|
||||
await expect(headingLocator).toBeVisible()
|
||||
})
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
|
||||
<<<<<<< HEAD
|
||||
// The heading is above it and should be in view now.
|
||||
const commandPaletteHeading = page.getByRole('heading', {
|
||||
name: 'Command Palette',
|
||||
@ -150,6 +235,63 @@ test.describe('Testing settings', () => {
|
||||
const hotkey = commandPaletteHeading.locator('+ div kbd')
|
||||
const text = process.platform === 'darwin' ? 'Command+K' : 'Control+K'
|
||||
await expect(hotkey).toHaveText(text)
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
// Verify the toast appeared
|
||||
await expect(
|
||||
page.getByText(`Set theme to "light" for this project`)
|
||||
).toBeVisible()
|
||||
// Check that the theme changed
|
||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||
|
||||
// Check that the user setting was not changed
|
||||
await page.getByRole('radio', { name: 'User' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('dark')
|
||||
|
||||
// Roll back to default "system" theme
|
||||
await page
|
||||
.getByText(
|
||||
'themeRoll back themeRoll back to match defaultThe overall appearance of the appl'
|
||||
)
|
||||
.hover()
|
||||
await page
|
||||
.getByRole('button', {
|
||||
name: 'Roll back theme',
|
||||
})
|
||||
.click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
|
||||
// Check that the project setting did not change
|
||||
await page.getByRole('radio', { name: 'Project' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
|
||||
=======
|
||||
// Verify the toast appeared
|
||||
await expect(
|
||||
page.getByText(`Set show debug panel to "false" for this project`)
|
||||
).toBeVisible()
|
||||
// Check that the theme changed
|
||||
await expect(paneButtonLocator).not.toBeVisible()
|
||||
|
||||
// Check that the user setting was not changed
|
||||
await page.getByRole('radio', { name: 'User' }).click()
|
||||
await expect(inputLocator).toBeChecked()
|
||||
|
||||
// Roll back to default of "off"
|
||||
await await page
|
||||
.getByText('show debug panelRoll back show debug panelRoll back to match')
|
||||
.hover()
|
||||
await page
|
||||
.getByRole('button', {
|
||||
name: 'Roll back show debug panel',
|
||||
})
|
||||
.click()
|
||||
await expect(inputLocator).not.toBeChecked()
|
||||
|
||||
// Check that the project setting did not change
|
||||
await page.getByRole('radio', { name: 'Project' }).click()
|
||||
await expect(
|
||||
page.locator('input[name="modeling-showDebugPanel"]')
|
||||
).not.toBeChecked()
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
})
|
||||
|
||||
test('Project and user settings can be reset', async ({ page }) => {
|
||||
@ -186,6 +328,7 @@ test.describe('Testing settings', () => {
|
||||
|
||||
// Set project-level value to 50
|
||||
await themeColorSetting.fill(settingValues.project)
|
||||
<<<<<<< HEAD
|
||||
|
||||
// Set user-level value to 120
|
||||
await userSettingsTab.click()
|
||||
@ -375,7 +518,14 @@ test.describe('Testing settings', () => {
|
||||
await page
|
||||
.getByRole('button', { name: 'Start Sketch' })
|
||||
.waitFor({ state: 'visible' })
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
await page
|
||||
.locator('select[name="app-theme"]')
|
||||
.selectOption({ value: 'light' })
|
||||
=======
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
|
||||
<<<<<<< HEAD
|
||||
const userSettingsTab = page.getByRole('radio', { name: 'User' })
|
||||
|
||||
// Open the settings modal with lower-right button
|
||||
@ -383,13 +533,39 @@ test.describe('Testing settings', () => {
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'Settings', exact: true })
|
||||
).toBeVisible()
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
// Verify the toast appeared
|
||||
await expect(
|
||||
page.getByText(`Set theme to "light" for this project`)
|
||||
).toBeVisible()
|
||||
// Check that the theme changed
|
||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
|
||||
=======
|
||||
// Set user-level value to 120
|
||||
await userSettingsTab.click()
|
||||
await themeColorSetting.fill(settingValues.user)
|
||||
await projectSettingsTab.click()
|
||||
})
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
|
||||
<<<<<<< HEAD
|
||||
const resetButton = page.getByRole('button', {
|
||||
name: 'Restore default settings',
|
||||
})
|
||||
// Default unit should be mm
|
||||
await resetButton.click()
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
// Check that the user setting was not changed
|
||||
await page.getByRole('radio', { name: 'User' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
=======
|
||||
await test.step('Reset project settings', async () => {
|
||||
// Click the reset settings button.
|
||||
await resetButton.click()
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
|
||||
<<<<<<< HEAD
|
||||
await test.step('Change modeling default unit within project tab', async () => {
|
||||
const changeUnitOfMeasureInProjectTab = async (unitOfMeasure: string) => {
|
||||
await test.step(`Set modeling default unit to ${unitOfMeasure}`, async () => {
|
||||
@ -409,7 +585,15 @@ test.describe('Testing settings', () => {
|
||||
await changeUnitOfMeasureInProjectTab('cm')
|
||||
await changeUnitOfMeasureInProjectTab('m')
|
||||
})
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
// Click the reset settings button.
|
||||
await page.getByRole('button', { name: 'Restore default settings' }).click()
|
||||
=======
|
||||
// Verify it is now set to the inherited user value
|
||||
await expect(themeColorSetting).toHaveValue(settingValues.default)
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
|
||||
<<<<<<< HEAD
|
||||
// Go to the user tab
|
||||
await userSettingsTab.click()
|
||||
await test.step('Change modeling default unit within user tab', async () => {
|
||||
@ -431,11 +615,33 @@ test.describe('Testing settings', () => {
|
||||
await changeUnitOfMeasureInUserTab('cm')
|
||||
await changeUnitOfMeasureInUserTab('m')
|
||||
})
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
// Verify it is now set to the default value
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
=======
|
||||
// Check that the user setting also rolled back
|
||||
await userSettingsTab.click()
|
||||
await expect(themeColorSetting).toHaveValue(settingValues.default)
|
||||
await projectSettingsTab.click()
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
|
||||
<<<<<<< HEAD
|
||||
// Close settings
|
||||
const settingsCloseButton = page.getByTestId('settings-close-button')
|
||||
await settingsCloseButton.click()
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
// Set the user theme to light.
|
||||
await page
|
||||
.locator('select[name="app-theme"]')
|
||||
.selectOption({ value: 'light' })
|
||||
=======
|
||||
// Set project-level value to 50 again to test the user-level reset
|
||||
await themeColorSetting.fill(settingValues.project)
|
||||
await userSettingsTab.click()
|
||||
})
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
|
||||
<<<<<<< HEAD
|
||||
await test.step('Change modeling default unit within command bar', async () => {
|
||||
const commands = page.getByRole('button', { name: 'Commands' })
|
||||
const changeUnitOfMeasureInCommandBar = async (unitOfMeasure: string) => {
|
||||
@ -445,13 +651,36 @@ test.describe('Testing settings', () => {
|
||||
'Settings · modeling · default unit'
|
||||
)
|
||||
await settingsModelingDefaultUnitCommand.click()
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
// Verify the toast appeared
|
||||
await expect(
|
||||
page.getByText(`Set theme to "light" as a user default`)
|
||||
).toBeVisible()
|
||||
// Check that the theme changed
|
||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
|
||||
=======
|
||||
await test.step('Reset user settings', async () => {
|
||||
// Change the setting and click the reset settings button.
|
||||
await themeColorSetting.fill(settingValues.user)
|
||||
await resetButton.click()
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
|
||||
<<<<<<< HEAD
|
||||
const commandOption = page.getByRole('option', {
|
||||
name: unitOfMeasure,
|
||||
exact: true,
|
||||
})
|
||||
await commandOption.click()
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
await page.getByRole('radio', { name: 'Project' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
|
||||
=======
|
||||
// Verify it is now set to the default value
|
||||
await expect(themeColorSetting).toHaveValue(settingValues.default)
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
|
||||
<<<<<<< HEAD
|
||||
const toastMessage = page.getByText(
|
||||
`Set default unit to "${unitOfMeasure}" for this project`
|
||||
)
|
||||
@ -491,6 +720,25 @@ test.describe('Testing settings', () => {
|
||||
await changeUnitOfMeasureInGizmo('mm', 'Millimeters')
|
||||
await changeUnitOfMeasureInGizmo('cm', 'Centimeters')
|
||||
await changeUnitOfMeasureInGizmo('m', 'Meters')
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
// Click the reset settings button.
|
||||
await page.getByRole('button', { name: 'Restore default settings' }).click()
|
||||
// Verify it is now set to the default value
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
|
||||
await page.getByRole('radio', { name: 'User' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
|
||||
// Click the reset settings button.
|
||||
await page.getByRole('button', { name: 'Restore default settings' }).click()
|
||||
|
||||
// Verify it is now set to the default value
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
=======
|
||||
// Check that the project setting also changed
|
||||
await projectSettingsTab.click()
|
||||
await expect(themeColorSetting).toHaveValue(settingValues.default)
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
7295
src-tauri/Cargo.lock
generated
Normal file
7295
src-tauri/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
47
src-tauri/Cargo.toml
Normal file
47
src-tauri/Cargo.toml
Normal file
@ -0,0 +1,47 @@
|
||||
[package]
|
||||
name = "app"
|
||||
version = "0.1.0"
|
||||
description = "The Zoo Modeling App"
|
||||
authors = ["Zoo Engineers <eng@zoo.dev>"]
|
||||
license = ""
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
default-run = "app"
|
||||
edition = "2021"
|
||||
rust-version = "1.70"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2.0.0-beta.18", features = [] }
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
kcl-lib = { version = "0.2", path = "../src/wasm-lib/kcl" }
|
||||
kittycad = "0.3.12"
|
||||
log = "0.4.21"
|
||||
mdns-sd = "0.11.1"
|
||||
oauth2 = "4.4.2"
|
||||
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
|
||||
serde_json = "1.0"
|
||||
tauri = { version = "2.0.0-beta.23", features = [ "devtools", "unstable"] }
|
||||
tauri-plugin-cli = { version = "2.0.0-beta.7" }
|
||||
tauri-plugin-deep-link = { version = "2.0.0-beta.8" }
|
||||
tauri-plugin-dialog = { version = "2.0.0-beta.6" }
|
||||
tauri-plugin-fs = { version = "2.0.0-beta.10" }
|
||||
tauri-plugin-http = { version = "2.0.0-beta.11" }
|
||||
tauri-plugin-log = { version = "2.0.0-beta.7" }
|
||||
tauri-plugin-os = { version = "2.0.0-beta.7" }
|
||||
tauri-plugin-persisted-scope = { version = "2.0.0-beta.10" }
|
||||
tauri-plugin-process = { version = "2.0.0-beta.7" }
|
||||
tauri-plugin-shell = { version = "2.0.0-beta.8" }
|
||||
tauri-plugin-updater = { version = "2.0.0-beta.9" }
|
||||
tokio = { version = "1.37.0", features = ["time", "fs", "process"] }
|
||||
toml = "0.8.2"
|
||||
url = "2.5.0"
|
||||
|
||||
[features]
|
||||
default = ["updater"]
|
||||
# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled.
|
||||
# If you use cargo directly instead of tauri's cli you can use this feature flag to switch between tauri's `dev` and `build` modes.
|
||||
# DO NOT REMOVE!!
|
||||
custom-protocol = ["tauri/custom-protocol"]
|
||||
updater = []
|
13
src/App.tsx
13
src/App.tsx
@ -28,6 +28,12 @@ import { CoreDumpManager } from 'lib/coredump'
|
||||
import { UnitsMenu } from 'components/UnitsMenu'
|
||||
|
||||
export function App() {
|
||||
<<<<<<< HEAD
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
useRefreshSettings(paths.FILE + 'SETTINGS')
|
||||
=======
|
||||
useRefreshSettings(PATHS.FILE + 'SETTINGS')
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
const { project, file } = useLoaderData() as IndexLoaderData
|
||||
useRefreshSettings(PATHS.FILE + 'SETTINGS')
|
||||
const navigate = useNavigate()
|
||||
@ -62,7 +68,14 @@ export function App() {
|
||||
e.preventDefault()
|
||||
})
|
||||
useHotkeyWrapper(
|
||||
<<<<<<< HEAD
|
||||
[isDesktop() ? 'mod + ,' : 'shift + mod + ,'],
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
[isTauri() ? 'mod + ,' : 'shift + mod + ,'],
|
||||
() => navigate(filePath + paths.SETTINGS),
|
||||
=======
|
||||
[isTauri() ? 'mod + ,' : 'shift + mod + ,'],
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
() => navigate(filePath + PATHS.SETTINGS),
|
||||
{
|
||||
splitKey: '|',
|
||||
|
@ -76,13 +76,27 @@ const router = createRouter([
|
||||
// Redirect to the file if we have a file path.
|
||||
if (projectStartupFile.length > 0) {
|
||||
return redirect(
|
||||
<<<<<<< HEAD
|
||||
PATHS.FILE + '/' + encodeURIComponent(projectStartupFile)
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
paths.FILE + '/' + encodeURIComponent(appState.current_file)
|
||||
=======
|
||||
PATHS.FILE + '/' + encodeURIComponent(appState.current_file)
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
return onDesktop
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
return inTauri
|
||||
? redirect(paths.HOME)
|
||||
: redirect(paths.FILE + '/%2F' + BROWSER_PROJECT_NAME)
|
||||
=======
|
||||
return inTauri
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
? redirect(PATHS.HOME)
|
||||
: redirect(PATHS.FILE + '/%2F' + BROWSER_PROJECT_NAME)
|
||||
},
|
||||
|
@ -53,10 +53,18 @@ export const FileMachineProvider = ({
|
||||
if (event.data && 'name' in event.data) {
|
||||
commandBarSend({ type: 'Close' })
|
||||
navigate(
|
||||
<<<<<<< HEAD
|
||||
`..${PATHS.FILE}/${encodeURIComponent(
|
||||
context.selectedDirectory +
|
||||
window.electron.path.sep +
|
||||
event.data.name
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
`${paths.FILE}/${encodeURIComponent(
|
||||
context.selectedDirectory + sep() + event.data.name
|
||||
=======
|
||||
`${PATHS.FILE}/${encodeURIComponent(
|
||||
context.selectedDirectory + sep() + event.data.name
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
)}`
|
||||
)
|
||||
} else if (
|
||||
@ -65,7 +73,13 @@ export const FileMachineProvider = ({
|
||||
event.data.path.endsWith(FILE_EXT)
|
||||
) {
|
||||
// Don't navigate to newly created directories
|
||||
<<<<<<< HEAD
|
||||
navigate(`..${PATHS.FILE}/${encodeURIComponent(event.data.path)}`)
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
navigate(`${paths.FILE}/${encodeURIComponent(event.data.path)}`)
|
||||
=======
|
||||
navigate(`${PATHS.FILE}/${encodeURIComponent(event.data.path)}`)
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
}
|
||||
},
|
||||
addFileToRenamingQueue: assign({
|
||||
@ -198,13 +212,29 @@ export const FileMachineProvider = ({
|
||||
|
||||
if (oldPath === file.path && project?.path) {
|
||||
// If we just renamed the current file, navigate to the new path
|
||||
<<<<<<< HEAD
|
||||
navigate(`..${PATHS.FILE}/${encodeURIComponent(newPath)}`)
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
navigate(paths.FILE + '/' + encodeURIComponent(newPath))
|
||||
=======
|
||||
navigate(PATHS.FILE + '/' + encodeURIComponent(newPath))
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
} else if (file?.path.includes(oldPath)) {
|
||||
// If we just renamed a directory that the current file is in, navigate to the new path
|
||||
navigate(
|
||||
<<<<<<< HEAD
|
||||
`..${PATHS.FILE}/${encodeURIComponent(
|
||||
file.path.replace(oldPath, newPath)
|
||||
)}`
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
paths.FILE +
|
||||
'/' +
|
||||
encodeURIComponent(file.path.replace(oldPath, newDirPath))
|
||||
=======
|
||||
PATHS.FILE +
|
||||
'/' +
|
||||
encodeURIComponent(file.path.replace(oldPath, newDirPath))
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
)
|
||||
}
|
||||
|
||||
@ -260,7 +290,13 @@ export const FileMachineProvider = ({
|
||||
file?.path.includes(event.data.path)) &&
|
||||
project?.path
|
||||
) {
|
||||
<<<<<<< HEAD
|
||||
navigate(`../${PATHS.FILE}/${encodeURIComponent(project.path)}`)
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
navigate(paths.FILE + '/' + encodeURIComponent(project.path))
|
||||
=======
|
||||
navigate(PATHS.FILE + '/' + encodeURIComponent(project.path))
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
}
|
||||
|
||||
return `Successfully deleted ${isDir ? 'folder' : 'file'} "${
|
||||
|
@ -1,4 +1,11 @@
|
||||
<<<<<<< HEAD
|
||||
import type { IndexLoaderData } from 'lib/types'
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
import type { FileEntry, IndexLoaderData } from 'lib/types'
|
||||
import { paths } from 'lib/paths'
|
||||
=======
|
||||
import type { FileEntry, IndexLoaderData } from 'lib/types'
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
import { PATHS } from 'lib/paths'
|
||||
import { ActionButton } from './ActionButton'
|
||||
import Tooltip from './Tooltip'
|
||||
@ -476,10 +483,16 @@ export const FileTreeInner = ({
|
||||
}, [documentHasFocus])
|
||||
|
||||
return (
|
||||
<<<<<<< HEAD
|
||||
<div
|
||||
className="overflow-auto pb-12 absolute inset-0"
|
||||
data-testid="file-pane-scroll-container"
|
||||
>
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
<div className="overflow-auto max-h-full pb-12">
|
||||
=======
|
||||
<div className="overflow-auto pb-12 absolute inset-0">
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
<ul
|
||||
className="m-0 p-0 text-sm"
|
||||
onClickCapture={(e) => {
|
||||
|
@ -3,8 +3,16 @@ import Tooltip from './Tooltip'
|
||||
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
||||
import { CustomIcon } from './CustomIcon'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
<<<<<<< HEAD
|
||||
import { PATHS } from 'lib/paths'
|
||||
import { createAndOpenNewProject } from 'lib/desktopFS'
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
import { createAndOpenNewProject } from 'lib/tauriFS'
|
||||
import { paths } from 'lib/paths'
|
||||
=======
|
||||
import { createAndOpenNewProject } from 'lib/tauriFS'
|
||||
import { PATHS } from 'lib/paths'
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
import { useAbsoluteFilePath } from 'hooks/useAbsoluteFilePath'
|
||||
import { useLspContext } from './LspProvider'
|
||||
import { openExternalBrowserIfDesktop } from 'lib/openWindow'
|
||||
|
@ -93,7 +93,15 @@ export function LowerRightControls({
|
||||
<Link
|
||||
to={
|
||||
location.pathname.includes(PATHS.FILE)
|
||||
<<<<<<< HEAD
|
||||
? filePath + PATHS.SETTINGS + '?tab=project'
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
location.pathname.includes(paths.FILE)
|
||||
? filePath + paths.SETTINGS + '?tab=project'
|
||||
: paths.HOME + paths.SETTINGS
|
||||
=======
|
||||
? filePath + PATHS.SETTINGS_PROJECT
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
: PATHS.HOME + PATHS.SETTINGS
|
||||
}
|
||||
data-testid="settings-link"
|
||||
|
@ -15,7 +15,14 @@ import { Extension } from '@codemirror/state'
|
||||
import { LanguageSupport } from '@codemirror/language'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { PATHS } from 'lib/paths'
|
||||
<<<<<<< HEAD
|
||||
import { FileEntry } from 'lib/project'
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
import { paths } from 'lib/paths'
|
||||
import { FileEntry } from 'lib/types'
|
||||
=======
|
||||
import { FileEntry } from 'lib/types'
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
import Worker from 'editor/plugins/lsp/worker.ts?worker'
|
||||
import {
|
||||
KclWorkerOptions,
|
||||
|
@ -2,7 +2,14 @@ import { Popover, Transition } from '@headlessui/react'
|
||||
import { ActionButton, ActionButtonProps } from './ActionButton'
|
||||
import { type IndexLoaderData } from 'lib/types'
|
||||
import { PATHS } from 'lib/paths'
|
||||
<<<<<<< HEAD
|
||||
import { isDesktop } from '../lib/isDesktop'
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
import { paths } from 'lib/paths'
|
||||
import { isTauri } from '../lib/isTauri'
|
||||
=======
|
||||
import { isTauri } from '../lib/isTauri'
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom'
|
||||
import { Fragment, useMemo } from 'react'
|
||||
import { Logo } from './Logo'
|
||||
|
@ -15,8 +15,16 @@ import { SettingsFieldInput } from './SettingsFieldInput'
|
||||
import { getInitialDefaultDir } from 'lib/desktop'
|
||||
import toast from 'react-hot-toast'
|
||||
import { APP_VERSION } from 'routes/Settings'
|
||||
<<<<<<< HEAD
|
||||
import { PATHS } from 'lib/paths'
|
||||
import { createAndOpenNewProject, getSettingsFolderPaths } from 'lib/desktopFS'
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
import { createAndOpenNewProject, getSettingsFolderPaths } from 'lib/tauriFS'
|
||||
import { paths } from 'lib/paths'
|
||||
=======
|
||||
import { createAndOpenNewProject, getSettingsFolderPaths } from 'lib/tauriFS'
|
||||
import { PATHS } from 'lib/paths'
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
import { useDotDotSlash } from 'hooks/useDotDotSlash'
|
||||
import { ForwardedRef, forwardRef, useEffect } from 'react'
|
||||
import { useLspContext } from 'components/LspProvider'
|
||||
@ -45,12 +53,20 @@ export const AllSettingsFields = forwardRef(
|
||||
location.pathname
|
||||
.replace(PATHS.FILE + '/', '')
|
||||
.replace(PATHS.SETTINGS, '')
|
||||
<<<<<<< HEAD
|
||||
.slice(
|
||||
0,
|
||||
decodeURI(location.pathname).lastIndexOf(
|
||||
window.electron.path.sep
|
||||
)
|
||||
)
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
.replace(paths.FILE + '/', '')
|
||||
.replace(paths.SETTINGS, '')
|
||||
.slice(0, decodeURI(location.pathname).lastIndexOf(sep()))
|
||||
=======
|
||||
.slice(0, decodeURI(location.pathname).lastIndexOf(sep()))
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
)
|
||||
: undefined
|
||||
|
||||
|
@ -1,5 +1,12 @@
|
||||
import { useMachine } from '@xstate/react'
|
||||
<<<<<<< HEAD
|
||||
import { useNavigate, useRouteLoaderData, useLocation } from 'react-router-dom'
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
import { useNavigate, useRouteLoaderData } from 'react-router-dom'
|
||||
import { paths } from 'lib/paths'
|
||||
=======
|
||||
import { useNavigate, useRouteLoaderData } from 'react-router-dom'
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
import { PATHS } from 'lib/paths'
|
||||
import { authMachine, TOKEN_PERSIST_KEY } from '../machines/authMachine'
|
||||
import withBaseUrl from '../lib/withBaseURL'
|
||||
@ -302,7 +309,14 @@ export const SettingsAuthProviderBase = ({
|
||||
logout()
|
||||
},
|
||||
goToIndexPage: () => {
|
||||
<<<<<<< HEAD
|
||||
if (location.pathname.includes(PATHS.SIGN_IN)) {
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
if (window.location.pathname.includes(paths.SIGN_IN)) {
|
||||
navigate(paths.INDEX)
|
||||
=======
|
||||
if (window.location.pathname.includes(PATHS.SIGN_IN)) {
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
navigate(PATHS.INDEX)
|
||||
}
|
||||
},
|
||||
|
@ -584,7 +584,7 @@ describe('Testing removeSingleConstraintInfo', () => {
|
||||
intersectTag: a,
|
||||
offset: 0 + 0
|
||||
}, %)
|
||||
|> tangentialArcTo([3.14 + 0, 13.14 + 0], %)`
|
||||
|> tangentialArcTo([3.14 + 0, 13.14 + 0], false, %)`
|
||||
test.each([
|
||||
[' line([3 + 0, 4], %)', 'arrayIndex', 1],
|
||||
[
|
||||
@ -626,7 +626,7 @@ describe('Testing removeSingleConstraintInfo', () => {
|
||||
'objectProperty',
|
||||
'offset',
|
||||
],
|
||||
['tangentialArcTo([3.14 + 0, 13.14], %)', 'arrayIndex', 1],
|
||||
['tangentialArcTo([3.14 + 0, 13.14], false, %)', 'arrayIndex', 1],
|
||||
])('stdlib fn: %s', async (expectedFinish, key, value) => {
|
||||
const ast = parse(code)
|
||||
if (err(ast)) throw ast
|
||||
|
@ -256,6 +256,14 @@ const runFilletTest = async (
|
||||
return new Error('Path to extrude node not found')
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
// const radius = createLiteral(5) as Value
|
||||
|
||||
=======
|
||||
// const radius = createLiteral(5) as Expr
|
||||
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
const result = addFillet(ast, pathToSegmentNode, pathToExtrudeNode, radius)
|
||||
if (err(result)) {
|
||||
return result
|
||||
@ -278,8 +286,8 @@ describe('Testing addFillet', () => {
|
||||
|> line([60.04, -55.72], %)
|
||||
|> line([1.29, -115.74], %)
|
||||
|> line([-87.24, -47.08], %)
|
||||
|> tangentialArcTo([56.15, -94.58], %)
|
||||
|> tangentialArcTo([14.68, -104.52], %)
|
||||
|> tangentialArcTo([56.15, -94.58], false, %)
|
||||
|> tangentialArcTo([14.68, -104.52], false, %)
|
||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||
|> close(%)
|
||||
const extrude001 = extrude(50, sketch001)
|
||||
@ -293,8 +301,8 @@ describe('Testing addFillet', () => {
|
||||
|> line([60.04, -55.72], %, $seg01)
|
||||
|> line([1.29, -115.74], %)
|
||||
|> line([-87.24, -47.08], %)
|
||||
|> tangentialArcTo([56.15, -94.58], %)
|
||||
|> tangentialArcTo([14.68, -104.52], %)
|
||||
|> tangentialArcTo([56.15, -94.58], false, %)
|
||||
|> tangentialArcTo([14.68, -104.52], false, %)
|
||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||
|> close(%)
|
||||
const extrude001 = extrude(50, sketch001)
|
||||
@ -321,8 +329,8 @@ const extrude001 = extrude(50, sketch001)
|
||||
|> line([60.04, -55.72], %)
|
||||
|> line([1.29, -115.74], %)
|
||||
|> line([-87.24, -47.08], %, $seg01)
|
||||
|> tangentialArcTo([56.15, -94.58], %)
|
||||
|> tangentialArcTo([14.68, -104.52], %)
|
||||
|> tangentialArcTo([56.15, -94.58], false, %)
|
||||
|> tangentialArcTo([14.68, -104.52], false, %)
|
||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||
|> close(%)
|
||||
const extrude001 = extrude(50, sketch001)
|
||||
@ -336,8 +344,8 @@ const extrude001 = extrude(50, sketch001)
|
||||
|> line([60.04, -55.72], %, $seg02)
|
||||
|> line([1.29, -115.74], %)
|
||||
|> line([-87.24, -47.08], %, $seg01)
|
||||
|> tangentialArcTo([56.15, -94.58], %)
|
||||
|> tangentialArcTo([14.68, -104.52], %)
|
||||
|> tangentialArcTo([56.15, -94.58], false, %)
|
||||
|> tangentialArcTo([14.68, -104.52], false, %)
|
||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||
|> close(%)
|
||||
const extrude001 = extrude(50, sketch001)
|
||||
@ -364,8 +372,8 @@ const extrude001 = extrude(50, sketch001)
|
||||
|> line([60.04, -55.72], %)
|
||||
|> line([1.29, -115.74], %)
|
||||
|> line([-87.24, -47.08], %, $seg03)
|
||||
|> tangentialArcTo([56.15, -94.58], %)
|
||||
|> tangentialArcTo([14.68, -104.52], %)
|
||||
|> tangentialArcTo([56.15, -94.58], false, %)
|
||||
|> tangentialArcTo([14.68, -104.52], false, %)
|
||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||
|> close(%)
|
||||
const extrude001 = extrude(50, sketch001)
|
||||
@ -379,8 +387,8 @@ const extrude001 = extrude(50, sketch001)
|
||||
|> line([60.04, -55.72], %)
|
||||
|> line([1.29, -115.74], %)
|
||||
|> line([-87.24, -47.08], %, $seg03)
|
||||
|> tangentialArcTo([56.15, -94.58], %)
|
||||
|> tangentialArcTo([14.68, -104.52], %)
|
||||
|> tangentialArcTo([56.15, -94.58], false, %)
|
||||
|> tangentialArcTo([14.68, -104.52], false, %)
|
||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||
|> close(%)
|
||||
const extrude001 = extrude(50, sketch001)
|
||||
@ -406,8 +414,8 @@ const extrude001 = extrude(50, sketch001)
|
||||
|> line([60.04, -55.72], %)
|
||||
|> line([1.29, -115.74], %)
|
||||
|> line([-87.24, -47.08], %, $seg03)
|
||||
|> tangentialArcTo([56.15, -94.58], %)
|
||||
|> tangentialArcTo([14.68, -104.52], %)
|
||||
|> tangentialArcTo([56.15, -94.58], false, %)
|
||||
|> tangentialArcTo([14.68, -104.52], false, %)
|
||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||
|> close(%)
|
||||
const extrude001 = extrude(50, sketch001)
|
||||
@ -421,8 +429,8 @@ const extrude001 = extrude(50, sketch001)
|
||||
|> line([60.04, -55.72], %, $seg01)
|
||||
|> line([1.29, -115.74], %)
|
||||
|> line([-87.24, -47.08], %, $seg03)
|
||||
|> tangentialArcTo([56.15, -94.58], %)
|
||||
|> tangentialArcTo([14.68, -104.52], %)
|
||||
|> tangentialArcTo([56.15, -94.58], false, %)
|
||||
|> tangentialArcTo([14.68, -104.52], false, %)
|
||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||
|> close(%)
|
||||
const extrude001 = extrude(50, sketch001)
|
||||
|
@ -4,7 +4,12 @@ import {
|
||||
ObjectExpression,
|
||||
PathToNode,
|
||||
Program,
|
||||
<<<<<<< HEAD
|
||||
ProgramMemory,
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
Value,
|
||||
=======
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
Expr,
|
||||
VariableDeclaration,
|
||||
VariableDeclarator,
|
||||
@ -159,7 +164,15 @@ export function addFillet(
|
||||
ast: Program,
|
||||
pathToSegmentNode: PathToNode,
|
||||
pathToExtrudeNode: PathToNode,
|
||||
<<<<<<< HEAD
|
||||
radius: Expr = createLiteral(5)
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
radius = createLiteral(5) as Value
|
||||
// shouldPipe = false, // TODO: Implement this feature
|
||||
=======
|
||||
radius = createLiteral(5) as Expr
|
||||
// shouldPipe = false, // TODO: Implement this feature
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
): { modifiedAst: Program; pathToFilletNode: PathToNode } | Error {
|
||||
// Clone AST to ensure safe mutations
|
||||
const astClone = structuredClone(ast)
|
||||
|
@ -270,7 +270,7 @@ describe('testing getConstraintInfo', () => {
|
||||
intersectTag: 'a',
|
||||
offset: 0
|
||||
}, %)
|
||||
|> tangentialArcTo([3.14, 13.14], %)`
|
||||
|> tangentialArcTo([3.14, 13.14], false, %)`
|
||||
const ast = parse(code)
|
||||
test.each([
|
||||
[
|
||||
@ -629,7 +629,7 @@ describe('testing getConstraintInfo', () => {
|
||||
intersectTag: 'a',
|
||||
offset: 0
|
||||
}, %)
|
||||
|> tangentialArcTo([3.14, 13.14], %)`
|
||||
|> tangentialArcTo([3.14, 13.14], false, %)`
|
||||
const ast = parse(code)
|
||||
test.each([
|
||||
[
|
||||
@ -783,7 +783,7 @@ describe('testing getConstraintInfo', () => {
|
||||
intersectTag: 'a',
|
||||
offset: 0 + 0
|
||||
}, %)
|
||||
|> tangentialArcTo([3.14 + 0, 13.14 + 0], %)`
|
||||
|> tangentialArcTo([3.14 + 0, 13.14 + 0], false, %)`
|
||||
const ast = parse(code)
|
||||
test.each([
|
||||
[
|
||||
|
@ -812,6 +812,7 @@ export const tangentialArcTo: SketchLineHelper = {
|
||||
}
|
||||
const newLine = createCallExpression('tangentialArcTo', [
|
||||
createArrayExpression([toX, toY]),
|
||||
createLiteral(false),
|
||||
createPipeSubstitution(),
|
||||
])
|
||||
if (pipe.type === 'PipeExpression') {
|
||||
|
@ -25,6 +25,7 @@ type OnboardingPaths = {
|
||||
|
||||
const SETTINGS = '/settings' as const
|
||||
|
||||
<<<<<<< HEAD
|
||||
export type ProjectRoute = {
|
||||
projectName: string | null
|
||||
projectPath: string
|
||||
@ -32,6 +33,10 @@ export type ProjectRoute = {
|
||||
currentFilePath: string | null
|
||||
}
|
||||
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
export const paths = {
|
||||
=======
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
export const PATHS = {
|
||||
INDEX: '/',
|
||||
HOME: '/home',
|
||||
|
@ -1,7 +1,15 @@
|
||||
import { ActionFunction, LoaderFunction, redirect } from 'react-router-dom'
|
||||
import { FileLoaderData, HomeLoaderData, IndexLoaderData } from './types'
|
||||
<<<<<<< HEAD
|
||||
import { getProjectMetaByRouteId, PATHS } from './paths'
|
||||
import { isDesktop } from './isDesktop'
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
import { isTauri } from './isTauri'
|
||||
import { getProjectMetaByRouteId, paths } from './paths'
|
||||
=======
|
||||
import { isTauri } from './isTauri'
|
||||
import { getProjectMetaByRouteId, PATHS } from './paths'
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
import { BROWSER_PATH } from 'lib/paths'
|
||||
import {
|
||||
BROWSER_FILE_NAME,
|
||||
@ -10,6 +18,15 @@ import {
|
||||
} from 'lib/constants'
|
||||
import { loadAndValidateSettings } from './settings/settingsUtils'
|
||||
import makeUrlPathRelative from './makeUrlPathRelative'
|
||||
<<<<<<< HEAD
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
import { sep } from '@tauri-apps/api/path'
|
||||
import { readTextFile } from '@tauri-apps/plugin-fs'
|
||||
import { codeManager, kclManager } from 'lib/singletons'
|
||||
=======
|
||||
import { sep } from '@tauri-apps/api/path'
|
||||
import { readTextFile } from '@tauri-apps/plugin-fs'
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
import { codeManager } from 'lib/singletons'
|
||||
import { fileSystemManager } from 'lang/std/fileSystemManager'
|
||||
import {
|
||||
@ -86,6 +103,7 @@ export const fileLoader: LoaderFunction = async (
|
||||
const { projectName, projectPath, currentFileName, currentFilePath } =
|
||||
projectPathData
|
||||
|
||||
<<<<<<< HEAD
|
||||
const urlObj = new URL(routerData.request.url)
|
||||
let code = ''
|
||||
|
||||
@ -120,8 +138,50 @@ export const fileLoader: LoaderFunction = async (
|
||||
// the file system and not the editor.
|
||||
codeManager.updateCurrentFilePath(currentFilePath)
|
||||
codeManager.updateCodeStateEditor(code)
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
if (!current_file_name || !current_file_path || !project_name) {
|
||||
return redirect(
|
||||
`${paths.FILE}/${encodeURIComponent(
|
||||
`${params.id}${isTauri() ? sep() : '/'}${PROJECT_ENTRYPOINT}`
|
||||
)}`
|
||||
)
|
||||
=======
|
||||
if (!current_file_name || !current_file_path || !project_name) {
|
||||
return redirect(
|
||||
`${PATHS.FILE}/${encodeURIComponent(
|
||||
`${params.id}${isTauri() ? sep() : '/'}${PROJECT_ENTRYPOINT}`
|
||||
)}`
|
||||
)
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
// TODO: PROJECT_ENTRYPOINT is hardcoded
|
||||
// until we support setting a project's entrypoint file
|
||||
const code = await readTextFile(current_file_path)
|
||||
|
||||
// Update both the state and the editor's code.
|
||||
// We explicitly do not write to the file here since we are loading from
|
||||
// the file system and not the editor.
|
||||
codeManager.updateCurrentFilePath(current_file_path)
|
||||
codeManager.updateCodeStateEditor(code)
|
||||
|
||||
// We don't want to call await on execute code since we don't want to block the UI
|
||||
kclManager.executeCode(true)
|
||||
|
||||
=======
|
||||
// TODO: PROJECT_ENTRYPOINT is hardcoded
|
||||
// until we support setting a project's entrypoint file
|
||||
const code = await readTextFile(current_file_path)
|
||||
|
||||
// Update both the state and the editor's code.
|
||||
// We explicitly do not write to the file here since we are loading from
|
||||
// the file system and not the editor.
|
||||
codeManager.updateCurrentFilePath(current_file_path)
|
||||
codeManager.updateCodeStateEditor(code)
|
||||
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
// Set the file system manager to the project path
|
||||
// So that WASM gets an updated path for operations
|
||||
fileSystemManager.dir = projectPath
|
||||
@ -181,7 +241,14 @@ export const fileLoader: LoaderFunction = async (
|
||||
export const homeLoader: LoaderFunction = async (): Promise<
|
||||
HomeLoaderData | Response
|
||||
> => {
|
||||
<<<<<<< HEAD
|
||||
if (!isDesktop()) {
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
if (!isTauri()) {
|
||||
return redirect(paths.FILE + '/%2F' + BROWSER_PROJECT_NAME)
|
||||
=======
|
||||
if (!isTauri()) {
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
return redirect(PATHS.FILE + '/%2F' + BROWSER_PROJECT_NAME)
|
||||
}
|
||||
const { configuration } = await loadAndValidateSettings()
|
||||
|
@ -42,7 +42,12 @@ import { Project } from 'lib/project'
|
||||
// This route only opens in the desktop context for now,
|
||||
// as defined in Router.tsx, so we can use the desktop APIs and types.
|
||||
const Home = () => {
|
||||
<<<<<<< HEAD
|
||||
const { projects: loadedProjects } = useLoaderData() as HomeLoaderData
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
useRefreshSettings(paths.HOME + 'SETTINGS')
|
||||
=======
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
useRefreshSettings(PATHS.HOME + 'SETTINGS')
|
||||
const { commandBarSend } = useCommandsContext()
|
||||
const navigate = useNavigate()
|
||||
@ -60,7 +65,14 @@ const Home = () => {
|
||||
e.preventDefault()
|
||||
})
|
||||
useHotkeys(
|
||||
<<<<<<< HEAD
|
||||
isDesktop() ? 'mod+,' : 'shift+mod+,',
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
isTauri() ? 'mod+,' : 'shift+mod+,',
|
||||
() => navigate(paths.HOME + paths.SETTINGS),
|
||||
=======
|
||||
isTauri() ? 'mod+,' : 'shift+mod+,',
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
() => navigate(PATHS.HOME + PATHS.SETTINGS),
|
||||
{
|
||||
splitKey: '|',
|
||||
@ -280,8 +292,14 @@ const Home = () => {
|
||||
<p className="my-4 text-sm text-chalkboard-80 dark:text-chalkboard-30">
|
||||
Loaded from{' '}
|
||||
<Link
|
||||
<<<<<<< HEAD
|
||||
data-testid="project-directory-settings-link"
|
||||
to={`${PATHS.HOME + PATHS.SETTINGS_USER}#projectDirectory`}
|
||||
||||||| parent of 1f27643b (Merge main)
|
||||
to="settings?tab=user#projectDirectory"
|
||||
=======
|
||||
to={`${PATHS.SETTINGS_USER}#projectDirectory`}
|
||||
>>>>>>> 1f27643b (Merge main)
|
||||
className="text-chalkboard-90 dark:text-chalkboard-20 underline underline-offset-2"
|
||||
>
|
||||
{settings.app.projectDirectory.current}
|
||||
|
@ -3309,7 +3309,7 @@ mod snapshot_tests {
|
||||
a,
|
||||
r#"const boxSketch = startSketchAt([0, 0])
|
||||
|> line([0, 10], %)
|
||||
|> tangentialArc([-5, 5], %)
|
||||
|> tangentialArcTo([-5, 5], true, %)
|
||||
|> line([5, -15], %)
|
||||
|> extrude(10, %)
|
||||
"#
|
||||
|
@ -5,7 +5,7 @@ use kittycad::types::OkWebSocketResponseData;
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
use crate::{
|
||||
ast::types::{parse_json_number_as_f64, TagDeclarator},
|
||||
ast::types::{parse_json_number_as_f64, KclNone, TagDeclarator},
|
||||
errors::{KclError, KclErrorDetails},
|
||||
executor::{
|
||||
DynamicState, ExecutorContext, ExtrudeGroup, ExtrudeGroupSet, ExtrudeSurface, KclValue, Metadata,
|
||||
@ -495,6 +495,9 @@ where
|
||||
{
|
||||
fn from_args(args: &'a Args, i: usize) -> Result<Self, KclError> {
|
||||
let Some(arg) = args.args.get(i) else { return Ok(None) };
|
||||
if let Some(_kcl_none) = KclNone::from_mem_item(arg) {
|
||||
return Ok(None);
|
||||
}
|
||||
let Some(val) = T::from_mem_item(arg) else {
|
||||
return Err(KclError::Semantic(KclErrorDetails {
|
||||
message: format!(
|
||||
@ -624,6 +627,7 @@ impl_from_arg_via_json!(u32);
|
||||
impl_from_arg_via_json!(u64);
|
||||
impl_from_arg_via_json!(f64);
|
||||
impl_from_arg_via_json!(bool);
|
||||
impl_from_arg_via_json!(KclNone);
|
||||
|
||||
impl_from_arg_for_array!(2);
|
||||
impl_from_arg_for_array!(3);
|
||||
|
@ -14,7 +14,7 @@ use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
executor::{
|
||||
BasePath, ExtrudeGroup, Face, GeoMeta, KclValue, Path, Plane, PlaneType, Point2d, Point3d, SketchGroup,
|
||||
SketchGroupSet, SketchSurface, SourceRange, TagEngineInfo, TagIdentifier, UserVal,
|
||||
SketchGroupSet, SketchSurface, TagEngineInfo, TagIdentifier, UserVal,
|
||||
},
|
||||
std::{
|
||||
utils::{
|
||||
@ -1634,8 +1634,6 @@ pub enum TangentialArcData {
|
||||
/// Offset of the arc, in degrees.
|
||||
offset: f64,
|
||||
},
|
||||
/// A point where the arc should end. Must lie in the same plane as the current path pen position. Must not be colinear with current path pen position.
|
||||
Point([f64; 2]),
|
||||
}
|
||||
|
||||
/// Draw a tangential arc.
|
||||
@ -1647,8 +1645,11 @@ pub async fn tangential_arc(args: Args) -> Result<KclValue, KclError> {
|
||||
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||
}
|
||||
|
||||
/// Starting at the current sketch's origin, draw a curved line segment along
|
||||
/// some part of an imaginary circle of the specified radius.
|
||||
/// Draw a curved line segment along some part of an imaginary circle of the specified radius.
|
||||
///
|
||||
/// If `relative` is true, the curve starts at the end of the previous path segment
|
||||
/// (i.e. the location of the "pen" which draws these lines). If `relative` is false,
|
||||
/// starts from the current sketch's origin.
|
||||
///
|
||||
/// The arc is constructed such that the last line segment is placed tangent
|
||||
/// to the imaginary circle of the specified radius. The resulting arc is the
|
||||
@ -1728,13 +1729,6 @@ async fn inner_tangential_arc(
|
||||
.await?;
|
||||
(center, to.into(), ccw)
|
||||
}
|
||||
TangentialArcData::Point(to) => {
|
||||
args.batch_modeling_cmd(id, tan_arc_to(&sketch_group, &to)).await?;
|
||||
// TODO: Figure out these calculations.
|
||||
let ccw = false;
|
||||
let center = Point2d { x: 0.0, y: 0.0 };
|
||||
(center, to, ccw)
|
||||
}
|
||||
};
|
||||
|
||||
let current_path = Path::TangentialArc {
|
||||
@ -1775,32 +1769,13 @@ fn tan_arc_to(sketch_group: &SketchGroup, to: &[f64; 2]) -> ModelingCmd {
|
||||
}
|
||||
}
|
||||
|
||||
fn too_few_args(source_range: SourceRange) -> KclError {
|
||||
KclError::Syntax(KclErrorDetails {
|
||||
source_ranges: vec![source_range],
|
||||
message: "too few arguments".to_owned(),
|
||||
})
|
||||
}
|
||||
|
||||
fn get_arg<I: Iterator>(it: &mut I, src: SourceRange) -> Result<I::Item, KclError> {
|
||||
it.next().ok_or_else(|| too_few_args(src))
|
||||
}
|
||||
|
||||
/// Draw a tangential arc to a specific point.
|
||||
pub async fn tangential_arc_to(args: Args) -> Result<KclValue, KclError> {
|
||||
let src = args.source_range;
|
||||
|
||||
// Get arguments to function call
|
||||
let mut it = args.args.iter();
|
||||
let to: [f64; 2] = get_arg(&mut it, src)?.get_json()?;
|
||||
let sketch_group: SketchGroup = get_arg(&mut it, src)?.get_json()?;
|
||||
let tag = if let Ok(memory_item) = get_arg(&mut it, src) {
|
||||
memory_item.get_json_opt()?
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let (to, relative, sketch_group, tag): ([f64; 2], bool, SketchGroup, Option<TagDeclarator>) =
|
||||
super::args::FromArgs::from_args(&args, 0)?;
|
||||
|
||||
let new_sketch_group = inner_tangential_arc_to(to, sketch_group, tag, args).await?;
|
||||
let new_sketch_group = inner_tangential_arc_to(to, relative, sketch_group, tag, args).await?;
|
||||
Ok(KclValue::new_user_val(new_sketch_group.meta.clone(), new_sketch_group))
|
||||
}
|
||||
|
||||
@ -1815,7 +1790,7 @@ pub async fn tangential_arc_to(args: Args) -> Result<KclValue, KclError> {
|
||||
/// angle: 60,
|
||||
/// length: 10,
|
||||
/// }, %)
|
||||
/// |> tangentialArcTo([15, 15], %)
|
||||
/// |> tangentialArcTo([15, 15], false, %)
|
||||
/// |> line([10, -15], %)
|
||||
/// |> close(%)
|
||||
///
|
||||
@ -1826,6 +1801,7 @@ pub async fn tangential_arc_to(args: Args) -> Result<KclValue, KclError> {
|
||||
}]
|
||||
async fn inner_tangential_arc_to(
|
||||
to: [f64; 2],
|
||||
relative: bool,
|
||||
sketch_group: SketchGroup,
|
||||
tag: Option<TagDeclarator>,
|
||||
args: Args,
|
||||
@ -1845,9 +1821,13 @@ async fn inner_tangential_arc_to(
|
||||
obtuse: true,
|
||||
});
|
||||
|
||||
let delta = [to_x - from.x, to_y - from.y];
|
||||
let to = if relative {
|
||||
[to_x, to_y]
|
||||
} else {
|
||||
[to_x - from.x, to_y - from.y]
|
||||
};
|
||||
let id = uuid::Uuid::new_v4();
|
||||
args.batch_modeling_cmd(id, tan_arc_to(&sketch_group, &delta)).await?;
|
||||
args.batch_modeling_cmd(id, tan_arc_to(&sketch_group, &to)).await?;
|
||||
|
||||
let current_path = Path::TangentialArcTo {
|
||||
base: BasePath {
|
||||
|
@ -9,40 +9,40 @@ let corner_radius = 5.0
|
||||
// because your wrist isn't a perfect cylindrical surface
|
||||
let brace_base = startSketchAt([corner_radius, 0])
|
||||
|> line([width - corner_radius, 0.0], %)
|
||||
|> tangentialArc([corner_radius, corner_radius], %)
|
||||
|> tangentialArcTo([corner_radius, corner_radius], true, %)
|
||||
|> yLine(25.0 - corner_radius, %)
|
||||
|> tangentialArc([-corner_radius, corner_radius], %)
|
||||
|> tangentialArcTo([-corner_radius, corner_radius], true, %)
|
||||
|> xLine(-(d_wrist_circumference[0] - (corner_radius * 2)), %)
|
||||
|> tangentialArc([-corner_radius, corner_radius], %)
|
||||
|> tangentialArcTo([-corner_radius, corner_radius], true, %)
|
||||
|> yLine(length - 25.0 - 23.0 - (corner_radius * 2), %)
|
||||
|> tangentialArc([corner_radius, corner_radius], %)
|
||||
|> tangentialArcTo([corner_radius, corner_radius], true, %)
|
||||
|> xLine(15.0 - (corner_radius * 2), %)
|
||||
|> tangentialArc([corner_radius, corner_radius], %)
|
||||
|> tangentialArcTo([corner_radius, corner_radius], true, %)
|
||||
|> yLine(23.0 - corner_radius, %)
|
||||
|> tangentialArc([-corner_radius, corner_radius], %)
|
||||
|> tangentialArcTo([-corner_radius, corner_radius], true, %)
|
||||
|> xLine(-(hand_thickness + 15.0 + 15.0 - (corner_radius * 2)), %)
|
||||
|> tangentialArc([-corner_radius, -corner_radius], %)
|
||||
|> tangentialArcTo([-corner_radius, -corner_radius], true, %)
|
||||
|> yLine(-(23.0 - corner_radius), %)
|
||||
|> tangentialArc([corner_radius, -corner_radius], %)
|
||||
|> tangentialArcTo([corner_radius, -corner_radius], true, %)
|
||||
|> xLine(15.0 - (corner_radius * 2), %)
|
||||
|> tangentialArc([corner_radius, -corner_radius], %)
|
||||
|> tangentialArcTo([corner_radius, -corner_radius], true, %)
|
||||
|> yLine(-(length - 25.0 - 23.0 - (corner_radius * 2)), %)
|
||||
|> tangentialArc([-corner_radius, -corner_radius], %)
|
||||
|> tangentialArcTo([-corner_radius, -corner_radius], true, %)
|
||||
|> xLine(-(d_wrist_circumference[1] + d_wrist_circumference[2] + d_wrist_circumference[3] - hand_thickness - corner_radius), %)
|
||||
|> tangentialArc([-corner_radius, -corner_radius], %)
|
||||
|> tangentialArcTo([-corner_radius, -corner_radius], true, %)
|
||||
|> yLine(-(25.0 - corner_radius), %)
|
||||
|> tangentialArc([corner_radius, -corner_radius], %)
|
||||
|> tangentialArcTo([corner_radius, -corner_radius], true, %)
|
||||
|> close(%)
|
||||
|
||||
let inner = startSketchAt([0, 0])
|
||||
|> xLine(1.0, %)
|
||||
|> tangentialArc([corner_radius, corner_radius], %)
|
||||
|> tangentialArcTo([corner_radius, corner_radius], true, %)
|
||||
|> yLine(25.0 - (corner_radius * 2), %)
|
||||
|> tangentialArc([-corner_radius, corner_radius], %)
|
||||
|> tangentialArcTo([-corner_radius, corner_radius], true, %)
|
||||
|> xLine(-1.0, %)
|
||||
|> tangentialArc([-corner_radius, -corner_radius], %)
|
||||
|> tangentialArcTo([-corner_radius, -corner_radius], true, %)
|
||||
|> yLine(-(25.0 - (corner_radius * 2)), %)
|
||||
|> tangentialArc([corner_radius, -corner_radius], %)
|
||||
|> tangentialArcTo([corner_radius, -corner_radius], true, %)
|
||||
|> close(%)
|
||||
|
||||
let final = brace_base
|
||||
|
@ -186,7 +186,7 @@ async fn kcl_test_negative_args() {
|
||||
async fn kcl_test_basic_tangential_arc_with_point() {
|
||||
let code = r#"const boxSketch = startSketchAt([0, 0])
|
||||
|> line([0, 10], %)
|
||||
|> tangentialArc([-5, 5], %)
|
||||
|> tangentialArcTo([-5, 5], true, %)
|
||||
|> line([5, -15], %)
|
||||
|> extrude(10, %)
|
||||
"#;
|
||||
@ -199,7 +199,7 @@ async fn kcl_test_basic_tangential_arc_with_point() {
|
||||
async fn kcl_test_basic_tangential_arc_to() {
|
||||
let code = r#"const boxSketch = startSketchAt([0, 0])
|
||||
|> line([0, 10], %)
|
||||
|> tangentialArcTo([-5, 15], %)
|
||||
|> tangentialArcTo([-5, 15], false, %)
|
||||
|> line([5, -15], %)
|
||||
|> extrude(10, %)
|
||||
"#;
|
||||
@ -332,7 +332,7 @@ const thing = other_circle([2, 2], 20)
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn kcl_test_rounded_with_holes() {
|
||||
let code = r#"fn tarc = (to, sketchGroup, tag?) => {
|
||||
return tangentialArcTo(to, sketchGroup, tag)
|
||||
return tangentialArcTo(to, false, sketchGroup, tag)
|
||||
}
|
||||
|
||||
fn roundedRectangle = (pos, w, l, cornerRadius) => {
|
||||
@ -1341,7 +1341,7 @@ async fn kcl_test_error_empty_start_sketch_on_string() {
|
||||
|> line([190.03, -118.13], %)
|
||||
|> line([-33.38, -202.86], %)
|
||||
|> line([-315.86, -64.2], %)
|
||||
|> tangentialArcTo([-147.66, 121.34], %)
|
||||
|> tangentialArcTo([-147.66, 121.34], false, %)
|
||||
|> close(%)
|
||||
|> extrude(100, %)
|
||||
|
||||
|
Reference in New Issue
Block a user