Compare commits
47 Commits
lf94/emerg
...
jtran/y-co
Author | SHA1 | Date | |
---|---|---|---|
b4fb903bd0 | |||
1b8688f274 | |||
397839da84 | |||
ac120838e5 | |||
e6a2ac9c4a | |||
6e7e6e96cf | |||
73e155d79b | |||
a782f26ec2 | |||
01076c3aed | |||
fe512611ac | |||
cba953c245 | |||
54ca6ea0b2 | |||
6a01608c3a | |||
530f15e04a | |||
725e59d987 | |||
54313c9b03 | |||
890d96496c | |||
35999366a7 | |||
2affc7271d | |||
d30fbf8b4b | |||
3f7e776464 | |||
79cff57f43 | |||
1cd2cd82b2 | |||
60e187bd3e | |||
c64175425b | |||
36464e6984 | |||
2f0002e53c | |||
482833c88f | |||
d9d0a72306 | |||
65cd9fab64 | |||
5e41e382ce | |||
1e3cb00092 | |||
d1a2bd01ca | |||
aca13d087b | |||
fcdde3e482 | |||
a1df3d0ffc | |||
1852e6167b | |||
29bf77bb82 | |||
e81b614523 | |||
5a5fe3bb95 | |||
0710f6e5f2 | |||
c9d5633647 | |||
f9419a98b5 | |||
999f72bccf | |||
9dbe74e008 | |||
88d9cdc52b | |||
2dd1f0f213 |
37
.github/ISSUE_TEMPLATE/cryptic_error.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
name: Cryptic KCL Error
|
||||||
|
description: File a bug report for source code that produces a confusing error
|
||||||
|
title: "[CRYPTIC]: "
|
||||||
|
labels: ["cryptic-error"]
|
||||||
|
assignees: []
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: "Thank you for taking the time to report a confusing error. Please provide as much information as possible to help us resolve it."
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: kcl
|
||||||
|
attributes:
|
||||||
|
label: Paste minimal KCL source that produces a cryptic error
|
||||||
|
description: Minimal KCL reproducer that produces a cryptic error
|
||||||
|
placeholder: "const ..."
|
||||||
|
render: javascript
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: expected-behavior
|
||||||
|
attributes:
|
||||||
|
label: Expected Behavior
|
||||||
|
description: Description of what you expected to happen (if you know).
|
||||||
|
placeholder: "I expected that..."
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: additional-context
|
||||||
|
attributes:
|
||||||
|
label: Additional Context
|
||||||
|
description: Add any other context about the problem here.
|
||||||
|
placeholder: "Anything else you want to add..."
|
||||||
|
validations:
|
||||||
|
required: false
|
38
README.md
@ -124,20 +124,40 @@ Before you submit a contribution PR to this repo, please ensure that:
|
|||||||
|
|
||||||
## Release a new version
|
## Release a new version
|
||||||
|
|
||||||
1. Bump the versions by running `./make-realease.sh` while on a fresh pull of main
|
#### 1. Bump the versions by running `./make-release.sh` and create a Cut Release PR
|
||||||
|
|
||||||
That will create the branch with the updated json files for you.
|
That will create the branch with the updated json files for you:
|
||||||
run `./make-release.sh` for a patch update
|
- run `./make-release.sh` or `./make-release.sh patch` for a patch update;
|
||||||
run `./make-release.sh "minor"` for minor
|
- run `./make-release.sh minor` for minor; or
|
||||||
run `./make-release.sh "major"` for major
|
- run `./make-release.sh major` for major.
|
||||||
|
|
||||||
After it runs you should just need to push the push the branch and open a PR (it will suggest a changelog for you too, delete any that are not user facing)
|
After it runs you should just need the push the branch and open a PR.
|
||||||
|
|
||||||
The PR may serve as a place to discuss the human-readable changelog and extra QA.
|
**Important:** It needs to be prefixed with `Cut release v` to build in release mode and a few other things to test in the best context possible, the intent would be for instance to have `Cut release v1.2.3` for the `v1.2.3` release candidate.
|
||||||
|
|
||||||
2. Merge the PR
|
The PR may then serve as a place to discuss the human-readable changelog and extra QA. The `make-release.sh` tool suggests a changelog for you too to be used as PR description, just make sure to delete lines that are not user facing.
|
||||||
|
|
||||||
|
#### 2. Smoke test artifacts from the Cut Release PR
|
||||||
|
|
||||||
|
The release builds can be find under the `artifact` zip, at the very bottom of the `ci` action page for each commit on this branch.
|
||||||
|
|
||||||
|
We don't have a strict process, but click around and check for anything obvious, posting results as comments in the Cut Release PR.
|
||||||
|
|
||||||
|
The other `ci` output in Cut Release PRs is `updater-test`, because we don't have a way to test this fully automated, we have a semi-automated process. Download updater-test zip file, install the app, run it, expect an updater prompt to a dummy v0.99.99, install it and check that the app comes back at that version (on both macOS and Windows).
|
||||||
|
|
||||||
|
#### 3. Merge the Cut Release PR
|
||||||
|
|
||||||
|
This will kick the `create-release` action, that creates a _Draft_ release out of this Cut Release PR merge after less than a minute, with the new version as title and Cut Release PR as description.
|
||||||
|
|
||||||
|
|
||||||
|
#### 4. Publish the release
|
||||||
|
|
||||||
|
Head over to https://github.com/KittyCAD/modeling-app/releases, the draft release corresponding to the merged Cut Release PR should show up at the top as _Draft_. Click on it, verify the content, and hit _Publish_.
|
||||||
|
|
||||||
|
#### 5. Profit
|
||||||
|
|
||||||
|
A new Action kicks in at https://github.com/KittyCAD/modeling-app/actions, which can be found under `release` event filter.
|
||||||
|
|
||||||
3. Profit (A new Action kicks in at https://github.com/KittyCAD/modeling-app/actions if the PR was correctly named)
|
|
||||||
|
|
||||||
## Fuzzing the parser
|
## Fuzzing the parser
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
@ -3099,6 +3099,49 @@ const sketch002 = startSketchOn(extrude001, $seg01)
|
|||||||
).not.toBeDisabled()
|
).not.toBeDisabled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Fillet button states test', async ({ page }) => {
|
||||||
|
const u = await getUtils(page)
|
||||||
|
await page.addInitScript(async () => {
|
||||||
|
localStorage.setItem(
|
||||||
|
'persistCode',
|
||||||
|
`const sketch001 = startSketchOn('XZ')
|
||||||
|
|> startProfileAt([-5, -5], %)
|
||||||
|
|> line([0, 10], %)
|
||||||
|
|> line([10, 0], %)
|
||||||
|
|> line([0, -10], %)
|
||||||
|
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||||
|
|> close(%)`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
await page.setViewportSize({ width: 1000, height: 500 })
|
||||||
|
await u.waitForAuthSkipAppStart()
|
||||||
|
await u.openDebugPanel()
|
||||||
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
|
const selectSegment = () => page.getByText(`line([10, 0], %)`).click()
|
||||||
|
const selectClose = () => page.getByText(`close(%)`).click()
|
||||||
|
const clickEmpty = () => page.mouse.click(950, 100)
|
||||||
|
|
||||||
|
// expect fillet button without any bodies in the scene
|
||||||
|
await selectSegment()
|
||||||
|
await expect(page.getByRole('button', { name: 'Fillet' })).toBeDisabled()
|
||||||
|
await clickEmpty()
|
||||||
|
await expect(page.getByRole('button', { name: 'Fillet' })).toBeDisabled()
|
||||||
|
|
||||||
|
// test fillet button with the body in the scene
|
||||||
|
const codeToAdd = `${await u.codeLocator.allInnerTexts()}
|
||||||
|
const extrude001 = extrude(10, sketch001)`
|
||||||
|
await u.codeLocator.fill(codeToAdd)
|
||||||
|
await selectSegment()
|
||||||
|
await expect(page.getByRole('button', { name: 'Fillet' })).toBeEnabled()
|
||||||
|
await selectClose()
|
||||||
|
await expect(page.getByRole('button', { name: 'Fillet' })).toBeDisabled()
|
||||||
|
await clickEmpty()
|
||||||
|
await expect(page.getByRole('button', { name: 'Fillet' })).toBeEnabled()
|
||||||
|
})
|
||||||
|
|
||||||
const removeAfterFirstParenthesis = (inputString: string) => {
|
const removeAfterFirstParenthesis = (inputString: string) => {
|
||||||
const index = inputString.indexOf('(')
|
const index = inputString.indexOf('(')
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
@ -3500,11 +3543,62 @@ test.describe('Command bar tests', () => {
|
|||||||
`const extrude001 = extrude(${KCL_DEFAULT_LENGTH}, sketch001)`
|
`const extrude001 = extrude(${KCL_DEFAULT_LENGTH}, sketch001)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
test('Command bar works and can change a setting', async ({ page }) => {
|
|
||||||
|
test('Fillet from command bar', async ({ page }) => {
|
||||||
|
await page.addInitScript(async () => {
|
||||||
|
localStorage.setItem(
|
||||||
|
'persistCode',
|
||||||
|
`const sketch001 = startSketchOn('XY')
|
||||||
|
|> startProfileAt([-5, -5], %)
|
||||||
|
|> line([0, 10], %)
|
||||||
|
|> line([10, 0], %)
|
||||||
|
|> line([0, -10], %)
|
||||||
|
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||||
|
|> close(%)
|
||||||
|
const extrude001 = extrude(-10, sketch001)`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const u = await getUtils(page)
|
||||||
|
await page.setViewportSize({ width: 1000, height: 500 })
|
||||||
|
await u.waitForAuthSkipAppStart()
|
||||||
|
await u.openDebugPanel()
|
||||||
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
|
const selectSegment = () => page.getByText(`line([0, -10], %)`).click()
|
||||||
|
|
||||||
|
await selectSegment()
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await page.getByRole('button', { name: 'Fillet' }).click()
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await page.keyboard.press('Enter')
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await page.keyboard.press('Enter')
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await expect(page.locator('.cm-activeLine')).toContainText(
|
||||||
|
`fillet({ radius: ${KCL_DEFAULT_LENGTH}, tags: [seg01] }, %)`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Command bar can change a setting, and switch back and forth between arguments', async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
await u.waitForAuthSkipAppStart()
|
await u.waitForAuthSkipAppStart()
|
||||||
|
|
||||||
|
const commandBarButton = page.getByRole('button', { name: 'Commands' })
|
||||||
|
const cmdSearchBar = page.getByPlaceholder('Search commands')
|
||||||
|
const themeOption = page.getByRole('option', {
|
||||||
|
name: 'theme',
|
||||||
|
exact: false,
|
||||||
|
})
|
||||||
|
const commandLevelArgButton = page.getByRole('button', { name: 'level' })
|
||||||
|
const commandThemeArgButton = page.getByRole('button', { name: 'value' })
|
||||||
|
// This selector changes after we set the setting
|
||||||
|
let commandOptionInput = page.getByPlaceholder('Select an option')
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
).not.toBeDisabled()
|
).not.toBeDisabled()
|
||||||
@ -3515,23 +3609,17 @@ test.describe('Command bar tests', () => {
|
|||||||
.or(page.getByRole('button', { name: '⌘K' }))
|
.or(page.getByRole('button', { name: '⌘K' }))
|
||||||
.click()
|
.click()
|
||||||
|
|
||||||
let cmdSearchBar = page.getByPlaceholder('Search commands')
|
|
||||||
await expect(cmdSearchBar).toBeVisible()
|
await expect(cmdSearchBar).toBeVisible()
|
||||||
await page.keyboard.press('Escape')
|
await page.keyboard.press('Escape')
|
||||||
cmdSearchBar = page.getByPlaceholder('Search commands')
|
|
||||||
await expect(cmdSearchBar).not.toBeVisible()
|
await expect(cmdSearchBar).not.toBeVisible()
|
||||||
|
|
||||||
// Now try the same, but with the keyboard shortcut, check focus
|
// Now try the same, but with the keyboard shortcut, check focus
|
||||||
await page.keyboard.press('Meta+K')
|
await page.keyboard.press('Meta+K')
|
||||||
cmdSearchBar = page.getByPlaceholder('Search commands')
|
|
||||||
await expect(cmdSearchBar).toBeVisible()
|
await expect(cmdSearchBar).toBeVisible()
|
||||||
await expect(cmdSearchBar).toBeFocused()
|
await expect(cmdSearchBar).toBeFocused()
|
||||||
|
|
||||||
// Try typing in the command bar
|
// Try typing in the command bar
|
||||||
await page.keyboard.type('theme')
|
await cmdSearchBar.fill('theme')
|
||||||
const themeOption = page.getByRole('option', {
|
|
||||||
name: 'Settings · app · theme',
|
|
||||||
})
|
|
||||||
await expect(themeOption).toBeVisible()
|
await expect(themeOption).toBeVisible()
|
||||||
await themeOption.click()
|
await themeOption.click()
|
||||||
const themeInput = page.getByPlaceholder('Select an option')
|
const themeInput = page.getByPlaceholder('Select an option')
|
||||||
@ -3553,6 +3641,24 @@ test.describe('Command bar tests', () => {
|
|||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
// Check that the theme changed
|
// Check that the theme changed
|
||||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||||
|
|
||||||
|
commandOptionInput = page.getByPlaceholder('system')
|
||||||
|
|
||||||
|
// Test case for https://github.com/KittyCAD/modeling-app/issues/2882
|
||||||
|
await commandBarButton.click()
|
||||||
|
await cmdSearchBar.focus()
|
||||||
|
await cmdSearchBar.fill('theme')
|
||||||
|
await themeOption.click()
|
||||||
|
await expect(commandThemeArgButton).toBeDisabled()
|
||||||
|
await commandOptionInput.focus()
|
||||||
|
await commandOptionInput.fill('lig')
|
||||||
|
await commandLevelArgButton.click()
|
||||||
|
await expect(commandLevelArgButton).toBeDisabled()
|
||||||
|
|
||||||
|
// Test case for https://github.com/KittyCAD/modeling-app/issues/2881
|
||||||
|
await commandThemeArgButton.click()
|
||||||
|
await expect(commandThemeArgButton).toBeDisabled()
|
||||||
|
await expect(commandLevelArgButton).toHaveText('level: project')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Command bar keybinding works from code editor and can change a setting', async ({
|
test('Command bar keybinding works from code editor and can change a setting', async ({
|
||||||
@ -3577,7 +3683,7 @@ test.describe('Command bar tests', () => {
|
|||||||
await expect(cmdSearchBar).toBeFocused()
|
await expect(cmdSearchBar).toBeFocused()
|
||||||
|
|
||||||
// Try typing in the command bar
|
// Try typing in the command bar
|
||||||
await page.keyboard.type('theme')
|
await cmdSearchBar.fill('theme')
|
||||||
const themeOption = page.getByRole('option', {
|
const themeOption = page.getByRole('option', {
|
||||||
name: 'Settings · app · theme',
|
name: 'Settings · app · theme',
|
||||||
})
|
})
|
||||||
@ -3648,7 +3754,9 @@ test.describe('Command bar tests', () => {
|
|||||||
await page.mouse.click(700, 200)
|
await page.mouse.click(700, 200)
|
||||||
|
|
||||||
// Assert that we're on the distance step
|
// Assert that we're on the distance step
|
||||||
await expect(page.getByRole('button', { name: 'distance' })).toBeDisabled()
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'distance', exact: false })
|
||||||
|
).toBeDisabled()
|
||||||
|
|
||||||
// Assert that the an alternative variable name is chosen,
|
// Assert that the an alternative variable name is chosen,
|
||||||
// since the default variable name is already in use (distance)
|
// since the default variable name is already in use (distance)
|
||||||
@ -3663,11 +3771,12 @@ test.describe('Command bar tests', () => {
|
|||||||
|
|
||||||
// Review step and argument hotkeys
|
// Review step and argument hotkeys
|
||||||
await expect(submitButton).toBeEnabled()
|
await expect(submitButton).toBeEnabled()
|
||||||
await page.keyboard.press('Backspace')
|
await expect(submitButton).toBeFocused()
|
||||||
|
await submitButton.press('Backspace')
|
||||||
|
|
||||||
// Assert we're back on the distance step
|
// Assert we're back on the distance step
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Distance 5', exact: false })
|
page.getByRole('button', { name: 'distance', exact: false })
|
||||||
).toBeDisabled()
|
).toBeDisabled()
|
||||||
|
|
||||||
await continueButton.click()
|
await continueButton.click()
|
||||||
@ -3691,6 +3800,47 @@ const extrude001 = extrude(distance001, sketch001)`.replace(
|
|||||||
) // remove newlines
|
) // remove newlines
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Can switch between sketch tools via command bar', async ({ page }) => {
|
||||||
|
const u = await getUtils(page)
|
||||||
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
|
await u.waitForAuthSkipAppStart()
|
||||||
|
|
||||||
|
const sketchButton = page.getByRole('button', { name: 'Start Sketch' })
|
||||||
|
const cmdBarButton = page.getByRole('button', { name: 'Commands' })
|
||||||
|
const rectangleToolCommand = page.getByRole('option', {
|
||||||
|
name: 'Rectangle',
|
||||||
|
})
|
||||||
|
const rectangleToolButton = page.getByRole('button', { name: 'Rectangle' })
|
||||||
|
const lineToolCommand = page.getByRole('option', { name: 'Line' })
|
||||||
|
const lineToolButton = page.getByRole('button', { name: 'Line' })
|
||||||
|
const arcToolCommand = page.getByRole('option', { name: 'Tangential Arc' })
|
||||||
|
const arcToolButton = page.getByRole('button', { name: 'Tangential Arc' })
|
||||||
|
|
||||||
|
// Start a sketch
|
||||||
|
await sketchButton.click()
|
||||||
|
await page.mouse.click(700, 200)
|
||||||
|
|
||||||
|
// Switch between sketch tools via the command bar
|
||||||
|
await expect(lineToolButton).toHaveAttribute('aria-pressed', 'true')
|
||||||
|
await cmdBarButton.click()
|
||||||
|
await rectangleToolCommand.click()
|
||||||
|
await expect(rectangleToolButton).toHaveAttribute('aria-pressed', 'true')
|
||||||
|
await cmdBarButton.click()
|
||||||
|
await lineToolCommand.click()
|
||||||
|
await expect(lineToolButton).toHaveAttribute('aria-pressed', 'true')
|
||||||
|
|
||||||
|
// Click in the scene a couple times to draw a line
|
||||||
|
// so tangential arc is valid
|
||||||
|
await page.mouse.click(700, 200)
|
||||||
|
await page.mouse.move(700, 300, { steps: 5 })
|
||||||
|
await page.mouse.click(700, 300)
|
||||||
|
|
||||||
|
// switch to tangential arc via command bar
|
||||||
|
await cmdBarButton.click()
|
||||||
|
await arcToolCommand.click()
|
||||||
|
await expect(arcToolButton).toHaveAttribute('aria-pressed', 'true')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test.describe('Regression tests', () => {
|
test.describe('Regression tests', () => {
|
||||||
@ -4642,10 +4792,10 @@ test.describe('Sketch tests', () => {
|
|||||||
// click extrude
|
// click extrude
|
||||||
await page.getByRole('button', { name: 'Extrude' }).click()
|
await page.getByRole('button', { name: 'Extrude' }).click()
|
||||||
|
|
||||||
// sketch selection should already have been made. "Selection 1 face" only show up when the selection has been made already
|
// sketch selection should already have been made. "Selection: 1 face" only show up when the selection has been made already
|
||||||
// otherwise the cmdbar would be waiting for a selection.
|
// otherwise the cmdbar would be waiting for a selection.
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Selection 1 face' })
|
page.getByRole('button', { name: 'selection : 1 face', exact: false })
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
})
|
})
|
||||||
test("Existing sketch with bad code delete user's code", async ({ page }) => {
|
test("Existing sketch with bad code delete user's code", async ({ page }) => {
|
||||||
@ -7071,6 +7221,7 @@ test.describe('Test network and connection issues', () => {
|
|||||||
|
|
||||||
// Expect the network to be up
|
// Expect the network to be up
|
||||||
await expect(page.getByText('Network Health (Connected)')).toBeVisible()
|
await expect(page.getByText('Network Health (Connected)')).toBeVisible()
|
||||||
|
await expect(page.getByTestId('loading-stream')).not.toBeAttached()
|
||||||
|
|
||||||
// Click off the code pane.
|
// Click off the code pane.
|
||||||
await page.mouse.click(100, 100)
|
await page.mouse.click(100, 100)
|
||||||
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 30 KiB |
@ -16,14 +16,14 @@ export const TEST_COLORS = {
|
|||||||
} as const
|
} as const
|
||||||
|
|
||||||
async function waitForPageLoad(page: Page) {
|
async function waitForPageLoad(page: Page) {
|
||||||
// wait for 'Loading stream...' spinner
|
|
||||||
await page.getByTestId('loading-stream').waitFor()
|
|
||||||
// wait for all spinners to be gone
|
// wait for all spinners to be gone
|
||||||
await page
|
await expect(page.getByTestId('loading')).not.toBeAttached({
|
||||||
.getByTestId('loading')
|
timeout: 20_000,
|
||||||
.waitFor({ state: 'detached', timeout: 20_000 })
|
})
|
||||||
|
|
||||||
await page.getByTestId('start-sketch').waitFor()
|
await expect(page.getByTestId('start-sketch')).toBeEnabled({
|
||||||
|
timeout: 20_000,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removeCurrentCode(page: Page) {
|
async function removeCurrentCode(page: Page) {
|
||||||
@ -471,8 +471,10 @@ export const doExport = async (
|
|||||||
page: Page
|
page: Page
|
||||||
): Promise<Paths> => {
|
): Promise<Paths> => {
|
||||||
await page.getByRole('button', { name: APP_NAME }).click()
|
await page.getByRole('button', { name: APP_NAME }).click()
|
||||||
await expect(page.getByRole('button', { name: 'Export Part' })).toBeVisible()
|
await expect(
|
||||||
await page.getByRole('button', { name: 'Export Part' }).click()
|
page.getByRole('button', { name: 'Export', exact: false })
|
||||||
|
).toBeVisible()
|
||||||
|
await page.getByRole('button', { name: 'Export', exact: false }).click()
|
||||||
await expect(page.getByTestId('command-bar')).toBeVisible()
|
await expect(page.getByTestId('command-bar')).toBeVisible()
|
||||||
|
|
||||||
// Go through export via command bar
|
// Go through export via command bar
|
||||||
|
@ -77,7 +77,7 @@ describe('ZMA authorized user flows', () => {
|
|||||||
const menuButton = await $('[data-testid="user-sidebar-toggle"]')
|
const menuButton = await $('[data-testid="user-sidebar-toggle"]')
|
||||||
await click(menuButton)
|
await click(menuButton)
|
||||||
|
|
||||||
const settingsButton = await $('[data-testid="settings-button"]')
|
const settingsButton = await $('[data-testid="user-settings"]')
|
||||||
await click(settingsButton)
|
await click(settingsButton)
|
||||||
|
|
||||||
const projectDirInput = await $('[data-testid="project-directory-input"]')
|
const projectDirInput = await $('[data-testid="project-directory-input"]')
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "untitled-app",
|
"name": "untitled-app",
|
||||||
"version": "0.24.0",
|
"version": "0.24.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/autocomplete": "^6.17.0",
|
"@codemirror/autocomplete": "^6.17.0",
|
||||||
|
@ -30,7 +30,7 @@ import { URI } from 'vscode-uri'
|
|||||||
import { LanguageServerClient } from '../client'
|
import { LanguageServerClient } from '../client'
|
||||||
import { CompletionItemKindMap } from './autocomplete'
|
import { CompletionItemKindMap } from './autocomplete'
|
||||||
import { addToken, SemanticToken } from './semantic-tokens'
|
import { addToken, SemanticToken } from './semantic-tokens'
|
||||||
import { deferExecution, posToOffset, formatMarkdownContents } from './util'
|
import { posToOffset, formatMarkdownContents } from './util'
|
||||||
import lspAutocompleteExt from './autocomplete'
|
import lspAutocompleteExt from './autocomplete'
|
||||||
import lspHoverExt from './hover'
|
import lspHoverExt from './hover'
|
||||||
import lspFormatExt from './format'
|
import lspFormatExt from './format'
|
||||||
@ -93,23 +93,10 @@ export class LanguageServerPlugin implements PluginValue {
|
|||||||
private doSemanticTokens: boolean = false
|
private doSemanticTokens: boolean = false
|
||||||
private doFoldingRanges: boolean = false
|
private doFoldingRanges: boolean = false
|
||||||
|
|
||||||
private _defferer = deferExecution((code: string) => {
|
// When a doc update needs to be sent to the server, this holds the
|
||||||
try {
|
// timeout handle for it. When null, the server has the up-to-date
|
||||||
// Update the state (not the editor) with the new code.
|
// document.
|
||||||
this.client.textDocumentDidChange({
|
private sendScheduled: number | null = null
|
||||||
textDocument: {
|
|
||||||
uri: this.getDocUri(),
|
|
||||||
version: this.documentVersion++,
|
|
||||||
},
|
|
||||||
contentChanges: [{ text: code }],
|
|
||||||
})
|
|
||||||
|
|
||||||
this.requestSemanticTokens()
|
|
||||||
this.updateFoldingRanges()
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e)
|
|
||||||
}
|
|
||||||
}, this.changesDelay)
|
|
||||||
|
|
||||||
constructor(options: LanguageServerOptions, private view: EditorView) {
|
constructor(options: LanguageServerOptions, private view: EditorView) {
|
||||||
this.client = options.client
|
this.client = options.client
|
||||||
@ -152,14 +139,9 @@ export class LanguageServerPlugin implements PluginValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update(viewUpdate: ViewUpdate) {
|
update(viewUpdate: ViewUpdate) {
|
||||||
// If the doc didn't change we can return early.
|
if (viewUpdate.docChanged) {
|
||||||
if (!viewUpdate.docChanged) {
|
this.scheduleSendDoc()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sendChange({
|
|
||||||
documentText: viewUpdate.state.doc.toString(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
@ -184,16 +166,6 @@ export class LanguageServerPlugin implements PluginValue {
|
|||||||
this.updateFoldingRanges()
|
this.updateFoldingRanges()
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendChange({ documentText }: { documentText: string }) {
|
|
||||||
if (!this.client.ready) return
|
|
||||||
|
|
||||||
this._defferer(documentText)
|
|
||||||
}
|
|
||||||
|
|
||||||
requestDiagnostics() {
|
|
||||||
this.sendChange({ documentText: this.getDocText() })
|
|
||||||
}
|
|
||||||
|
|
||||||
async requestHoverTooltip(
|
async requestHoverTooltip(
|
||||||
view: EditorView,
|
view: EditorView,
|
||||||
{ line, character }: { line: number; character: number }
|
{ line, character }: { line: number; character: number }
|
||||||
@ -204,7 +176,7 @@ export class LanguageServerPlugin implements PluginValue {
|
|||||||
)
|
)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
this.sendChange({ documentText: this.getDocText() })
|
this.ensureDocSent()
|
||||||
const result = await this.client.textDocumentHover({
|
const result = await this.client.textDocumentHover({
|
||||||
textDocument: { uri: this.getDocUri() },
|
textDocument: { uri: this.getDocUri() },
|
||||||
position: { line, character },
|
position: { line, character },
|
||||||
@ -227,6 +199,42 @@ export class LanguageServerPlugin implements PluginValue {
|
|||||||
return { pos, end, create: (view) => ({ dom }), above: true }
|
return { pos, end, create: (view) => ({ dom }), above: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scheduleSendDoc() {
|
||||||
|
if (this.sendScheduled != null) window.clearTimeout(this.sendScheduled)
|
||||||
|
this.sendScheduled = window.setTimeout(
|
||||||
|
() => this.sendDoc(),
|
||||||
|
this.changesDelay
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
sendDoc() {
|
||||||
|
if (this.sendScheduled != null) {
|
||||||
|
window.clearTimeout(this.sendScheduled)
|
||||||
|
this.sendScheduled = null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.client.ready) return
|
||||||
|
try {
|
||||||
|
// Update the state (not the editor) with the new code.
|
||||||
|
this.client.textDocumentDidChange({
|
||||||
|
textDocument: {
|
||||||
|
uri: this.getDocUri(),
|
||||||
|
version: this.documentVersion++,
|
||||||
|
},
|
||||||
|
contentChanges: [{ text: this.view.state.doc.toString() }],
|
||||||
|
})
|
||||||
|
|
||||||
|
this.requestSemanticTokens()
|
||||||
|
this.updateFoldingRanges()
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureDocSent() {
|
||||||
|
if (this.sendScheduled != null) this.sendDoc()
|
||||||
|
}
|
||||||
|
|
||||||
async getFoldingRanges(): Promise<LSP.FoldingRange[] | null> {
|
async getFoldingRanges(): Promise<LSP.FoldingRange[] | null> {
|
||||||
if (
|
if (
|
||||||
!this.doFoldingRanges ||
|
!this.doFoldingRanges ||
|
||||||
@ -284,13 +292,7 @@ export class LanguageServerPlugin implements PluginValue {
|
|||||||
)
|
)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
this.client.textDocumentDidChange({
|
this.ensureDocSent()
|
||||||
textDocument: {
|
|
||||||
uri: this.getDocUri(),
|
|
||||||
version: this.documentVersion++,
|
|
||||||
},
|
|
||||||
contentChanges: [{ text: this.getDocText() }],
|
|
||||||
})
|
|
||||||
|
|
||||||
const result = await this.client.textDocumentFormatting({
|
const result = await this.client.textDocumentFormatting({
|
||||||
textDocument: { uri: this.getDocUri() },
|
textDocument: { uri: this.getDocUri() },
|
||||||
@ -330,9 +332,7 @@ export class LanguageServerPlugin implements PluginValue {
|
|||||||
)
|
)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
this.sendChange({
|
this.ensureDocSent()
|
||||||
documentText: context.state.doc.toString(),
|
|
||||||
})
|
|
||||||
|
|
||||||
const result = await this.client.textDocumentCompletion({
|
const result = await this.client.textDocumentCompletion({
|
||||||
textDocument: { uri: this.getDocUri() },
|
textDocument: { uri: this.getDocUri() },
|
||||||
|
138
src-tauri/Cargo.lock
generated
@ -332,7 +332,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -361,13 +361,13 @@ checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.80"
|
version = "0.1.81"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
|
checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -407,7 +407,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -550,7 +550,7 @@ dependencies = [
|
|||||||
"proc-macro-crate 3.1.0",
|
"proc-macro-crate 3.1.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
"syn_derive",
|
"syn_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -792,9 +792,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.7"
|
version = "4.5.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f"
|
checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
@ -802,9 +802,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_builder"
|
name = "clap_builder"
|
||||||
version = "4.5.7"
|
version = "4.5.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f"
|
checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
@ -816,14 +816,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "4.5.5"
|
version = "4.5.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6"
|
checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1073,7 +1073,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
|
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1083,7 +1083,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
|
checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1107,7 +1107,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"strsim 0.10.0",
|
"strsim 0.10.0",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1118,7 +1118,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1179,7 +1179,7 @@ checksum = "4078275de501a61ceb9e759d37bdd3d7210e654dbc167ac1a3678ef4435ed57b"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1216,7 +1216,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_tokenstream",
|
"serde_tokenstream",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1227,7 +1227,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1288,7 +1288,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1320,7 +1320,7 @@ checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1427,7 +1427,7 @@ checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1588,7 +1588,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1704,7 +1704,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1980,7 +1980,7 @@ dependencies = [
|
|||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2008,7 +2008,7 @@ dependencies = [
|
|||||||
"inflections",
|
"inflections",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2083,7 +2083,7 @@ dependencies = [
|
|||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2571,7 +2571,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
version = "0.1.70"
|
version = "0.1.72"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"approx",
|
"approx",
|
||||||
@ -3377,7 +3377,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"regex-syntax 0.8.3",
|
"regex-syntax 0.8.3",
|
||||||
"structmeta",
|
"structmeta",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3496,7 +3496,7 @@ dependencies = [
|
|||||||
"phf_shared 0.11.2",
|
"phf_shared 0.11.2",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3564,7 +3564,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4438,7 +4438,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"serde_derive_internals",
|
"serde_derive_internals",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4523,9 +4523,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.203"
|
version = "1.0.204"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
|
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
@ -4552,13 +4552,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.203"
|
version = "1.0.204"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
|
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4569,7 +4569,7 @@ checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4602,7 +4602,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4623,7 +4623,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"serde",
|
"serde",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4665,7 +4665,7 @@ dependencies = [
|
|||||||
"darling",
|
"darling",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4933,7 +4933,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"structmeta-derive",
|
"structmeta-derive",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4944,7 +4944,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4966,7 +4966,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4999,9 +4999,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.68"
|
version = "2.0.71"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9"
|
checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -5017,7 +5017,7 @@ dependencies = [
|
|||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -5034,7 +5034,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -5251,7 +5251,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
"tauri-utils",
|
"tauri-utils",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"time",
|
"time",
|
||||||
@ -5269,7 +5269,7 @@ dependencies = [
|
|||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
"tauri-codegen",
|
"tauri-codegen",
|
||||||
"tauri-utils",
|
"tauri-utils",
|
||||||
]
|
]
|
||||||
@ -5627,22 +5627,22 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.61"
|
version = "1.0.62"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
|
checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.61"
|
version = "1.0.62"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -5740,7 +5740,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -5940,7 +5940,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -5969,7 +5969,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6099,7 +6099,7 @@ checksum = "c88cc88fd23b5a04528f3a8436024f20010a16ec18eb23c164b1242f65860130"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -6280,9 +6280,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.9.1"
|
version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439"
|
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.14",
|
"getrandom 0.2.14",
|
||||||
"serde",
|
"serde",
|
||||||
@ -6316,7 +6316,7 @@ dependencies = [
|
|||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6415,7 +6415,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -6449,7 +6449,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
@ -6590,7 +6590,7 @@ checksum = "ac1345798ecd8122468840bcdf1b95e5dc6d2206c5e4b0eafa078d061f59c9bc"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6696,7 +6696,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6707,7 +6707,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -7159,7 +7159,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.68",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -80,5 +80,5 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"productName": "Zoo Modeling App",
|
"productName": "Zoo Modeling App",
|
||||||
"version": "0.24.0"
|
"version": "0.24.3"
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ export function App() {
|
|||||||
}, [projectName, projectPath])
|
}, [projectName, projectPath])
|
||||||
|
|
||||||
useHotKeyListener()
|
useHotKeyListener()
|
||||||
const { context } = useModelingContext()
|
const { context, state } = useModelingContext()
|
||||||
|
|
||||||
const { auth, settings } = useSettingsAuthContext()
|
const { auth, settings } = useSettingsAuthContext()
|
||||||
const token = auth?.context?.token
|
const token = auth?.context?.token
|
||||||
@ -57,7 +57,6 @@ export function App() {
|
|||||||
const {
|
const {
|
||||||
app: { onboardingStatus },
|
app: { onboardingStatus },
|
||||||
} = settings.context
|
} = settings.context
|
||||||
const { state } = useModelingContext()
|
|
||||||
|
|
||||||
useHotkeys('backspace', (e) => {
|
useHotkeys('backspace', (e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
@ -39,3 +39,32 @@ export const AppStateProvider = ({ children }: { children: ReactNode }) => {
|
|||||||
</AppStateContext.Provider>
|
</AppStateContext.Provider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface AppStream {
|
||||||
|
mediaStream: MediaStream
|
||||||
|
setMediaStream: (mediaStream: MediaStream) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const AppStreamContext = createContext<AppStream>({
|
||||||
|
mediaStream: undefined as unknown as MediaStream,
|
||||||
|
setMediaStream: () => {},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const useAppStream = () => useContext(AppStreamContext)
|
||||||
|
|
||||||
|
export const AppStreamProvider = ({ children }: { children: ReactNode }) => {
|
||||||
|
const [mediaStream, setMediaStream] = useState<MediaStream>(
|
||||||
|
undefined as unknown as MediaStream
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AppStreamContext.Provider
|
||||||
|
value={{
|
||||||
|
mediaStream,
|
||||||
|
setMediaStream,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</AppStreamContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -16,6 +16,7 @@ import {
|
|||||||
canRectangleTool,
|
canRectangleTool,
|
||||||
isEditingExistingSketch,
|
isEditingExistingSketch,
|
||||||
} from 'machines/modelingMachine'
|
} from 'machines/modelingMachine'
|
||||||
|
import { DEV } from 'env'
|
||||||
|
|
||||||
export function Toolbar({
|
export function Toolbar({
|
||||||
className = '',
|
className = '',
|
||||||
@ -60,7 +61,7 @@ export function Toolbar({
|
|||||||
? send('CancelSketch')
|
? send('CancelSketch')
|
||||||
: send({
|
: send({
|
||||||
type: 'change tool',
|
type: 'change tool',
|
||||||
data: 'line',
|
data: { tool: 'line' },
|
||||||
}),
|
}),
|
||||||
{ enabled: !disableLineButton, scopes: ['sketch'] }
|
{ enabled: !disableLineButton, scopes: ['sketch'] }
|
||||||
)
|
)
|
||||||
@ -75,7 +76,7 @@ export function Toolbar({
|
|||||||
? send('CancelSketch')
|
? send('CancelSketch')
|
||||||
: send({
|
: send({
|
||||||
type: 'change tool',
|
type: 'change tool',
|
||||||
data: 'tangentialArc',
|
data: { tool: 'tangentialArc' },
|
||||||
}),
|
}),
|
||||||
{ enabled: !disableTangentialArc, scopes: ['sketch'] }
|
{ enabled: !disableTangentialArc, scopes: ['sketch'] }
|
||||||
)
|
)
|
||||||
@ -89,7 +90,7 @@ export function Toolbar({
|
|||||||
? send('CancelSketch')
|
? send('CancelSketch')
|
||||||
: send({
|
: send({
|
||||||
type: 'change tool',
|
type: 'change tool',
|
||||||
data: 'rectangle',
|
data: { tool: 'rectangle' },
|
||||||
}),
|
}),
|
||||||
{ enabled: !disableRectangle, scopes: ['sketch'] }
|
{ enabled: !disableRectangle, scopes: ['sketch'] }
|
||||||
)
|
)
|
||||||
@ -114,10 +115,20 @@ export function Toolbar({
|
|||||||
() =>
|
() =>
|
||||||
commandBarSend({
|
commandBarSend({
|
||||||
type: 'Find and select command',
|
type: 'Find and select command',
|
||||||
data: { name: 'Extrude', ownerMachine: 'modeling' },
|
data: { name: 'Extrude', groupId: 'modeling' },
|
||||||
}),
|
}),
|
||||||
{ enabled: !disableAllButtons, scopes: ['modeling'] }
|
{ enabled: !disableAllButtons, scopes: ['modeling'] }
|
||||||
)
|
)
|
||||||
|
const disableFillet = !state.can('Fillet') || disableAllButtons
|
||||||
|
useHotkeys(
|
||||||
|
'f',
|
||||||
|
() =>
|
||||||
|
commandBarSend({
|
||||||
|
type: 'Find and select command',
|
||||||
|
data: { name: 'Fillet', groupId: 'modeling' },
|
||||||
|
}),
|
||||||
|
{ enabled: !disableFillet, scopes: ['modeling'] }
|
||||||
|
)
|
||||||
|
|
||||||
function handleToolbarButtonsWheelEvent(ev: WheelEvent<HTMLSpanElement>) {
|
function handleToolbarButtonsWheelEvent(ev: WheelEvent<HTMLSpanElement>) {
|
||||||
const span = toolbarButtonsRef.current
|
const span = toolbarButtonsRef.current
|
||||||
@ -263,7 +274,7 @@ export function Toolbar({
|
|||||||
? send('CancelSketch')
|
? send('CancelSketch')
|
||||||
: send({
|
: send({
|
||||||
type: 'change tool',
|
type: 'change tool',
|
||||||
data: 'line',
|
data: { tool: 'line' },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
aria-pressed={state?.matches('Sketch.Line tool')}
|
aria-pressed={state?.matches('Sketch.Line tool')}
|
||||||
@ -293,7 +304,7 @@ export function Toolbar({
|
|||||||
? send('CancelSketch')
|
? send('CancelSketch')
|
||||||
: send({
|
: send({
|
||||||
type: 'change tool',
|
type: 'change tool',
|
||||||
data: 'tangentialArc',
|
data: { tool: 'tangentialArc' },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
aria-pressed={state.matches('Sketch.Tangential arc to')}
|
aria-pressed={state.matches('Sketch.Tangential arc to')}
|
||||||
@ -323,7 +334,7 @@ export function Toolbar({
|
|||||||
? send('CancelSketch')
|
? send('CancelSketch')
|
||||||
: send({
|
: send({
|
||||||
type: 'change tool',
|
type: 'change tool',
|
||||||
data: 'rectangle',
|
data: { tool: 'rectangle' },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
aria-pressed={state.matches('Sketch.Rectangle tool')}
|
aria-pressed={state.matches('Sketch.Rectangle tool')}
|
||||||
@ -378,7 +389,7 @@ export function Toolbar({
|
|||||||
onClick={() =>
|
onClick={() =>
|
||||||
commandBarSend({
|
commandBarSend({
|
||||||
type: 'Find and select command',
|
type: 'Find and select command',
|
||||||
data: { name: 'Extrude', ownerMachine: 'modeling' },
|
data: { name: 'Extrude', groupId: 'modeling' },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
disabled={!state.can('Extrude') || disableAllButtons}
|
disabled={!state.can('Extrude') || disableAllButtons}
|
||||||
@ -404,6 +415,36 @@ export function Toolbar({
|
|||||||
</ActionButton>
|
</ActionButton>
|
||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
|
{state.matches('idle') && (DEV || (window as any)._enableFillet) && (
|
||||||
|
<li className="contents">
|
||||||
|
<ActionButton
|
||||||
|
className={buttonClassName}
|
||||||
|
Element="button"
|
||||||
|
onClick={() =>
|
||||||
|
commandBarSend({
|
||||||
|
type: 'Find and select command',
|
||||||
|
data: { name: 'Fillet', groupId: 'modeling' },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
disabled={disableFillet}
|
||||||
|
title={disableFillet ? 'fillet' : "edge can't be filleted"}
|
||||||
|
iconStart={{
|
||||||
|
icon: 'fillet', // todo: add fillet icon
|
||||||
|
iconClassName,
|
||||||
|
bgClassName,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Fillet
|
||||||
|
<Tooltip
|
||||||
|
delay={1250}
|
||||||
|
position="bottom"
|
||||||
|
className="!px-2 !text-xs"
|
||||||
|
>
|
||||||
|
Shortcut: F
|
||||||
|
</Tooltip>
|
||||||
|
</ActionButton>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
</ul>
|
</ul>
|
||||||
</menu>
|
</menu>
|
||||||
)
|
)
|
||||||
|
@ -47,7 +47,6 @@ import {
|
|||||||
PipeExpression,
|
PipeExpression,
|
||||||
Program,
|
Program,
|
||||||
ProgramMemory,
|
ProgramMemory,
|
||||||
programMemoryInit,
|
|
||||||
recast,
|
recast,
|
||||||
SketchGroup,
|
SketchGroup,
|
||||||
ExtrudeGroup,
|
ExtrudeGroup,
|
||||||
@ -130,7 +129,7 @@ export const HIDE_HOVER_SEGMENT_LENGTH = 60 // in pixels
|
|||||||
export class SceneEntities {
|
export class SceneEntities {
|
||||||
engineCommandManager: EngineCommandManager
|
engineCommandManager: EngineCommandManager
|
||||||
scene: Scene
|
scene: Scene
|
||||||
sceneProgramMemory: ProgramMemory = { root: {}, return: null }
|
sceneProgramMemory: ProgramMemory = ProgramMemory.empty()
|
||||||
activeSegments: { [key: string]: Group } = {}
|
activeSegments: { [key: string]: Group } = {}
|
||||||
intersectionPlane: Mesh | null = null
|
intersectionPlane: Mesh | null = null
|
||||||
axisGroup: Group | null = null
|
axisGroup: Group | null = null
|
||||||
@ -550,9 +549,9 @@ export class SceneEntities {
|
|||||||
const variableDeclarationName =
|
const variableDeclarationName =
|
||||||
_node1.node?.declarations?.[0]?.id?.name || ''
|
_node1.node?.declarations?.[0]?.id?.name || ''
|
||||||
|
|
||||||
const sg = kclManager.programMemory.root[
|
const sg = kclManager.programMemory.get(
|
||||||
variableDeclarationName
|
variableDeclarationName
|
||||||
] as SketchGroup
|
) as SketchGroup
|
||||||
const lastSeg = sg.value.slice(-1)[0] || sg.start
|
const lastSeg = sg.value.slice(-1)[0] || sg.start
|
||||||
|
|
||||||
const index = sg.value.length // because we've added a new segment that's not in the memory yet, no need for `-1`
|
const index = sg.value.length // because we've added a new segment that's not in the memory yet, no need for `-1`
|
||||||
@ -768,9 +767,9 @@ export class SceneEntities {
|
|||||||
programMemoryOverride,
|
programMemoryOverride,
|
||||||
})
|
})
|
||||||
this.sceneProgramMemory = programMemory
|
this.sceneProgramMemory = programMemory
|
||||||
const sketchGroup = programMemory.root[
|
const sketchGroup = programMemory.get(
|
||||||
variableDeclarationName
|
variableDeclarationName
|
||||||
] as SketchGroup
|
) as SketchGroup
|
||||||
const sgPaths = sketchGroup.value
|
const sgPaths = sketchGroup.value
|
||||||
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
||||||
|
|
||||||
@ -820,9 +819,9 @@ export class SceneEntities {
|
|||||||
|
|
||||||
// Prepare to update the THREEjs scene
|
// Prepare to update the THREEjs scene
|
||||||
this.sceneProgramMemory = programMemory
|
this.sceneProgramMemory = programMemory
|
||||||
const sketchGroup = programMemory.root[
|
const sketchGroup = programMemory.get(
|
||||||
variableDeclarationName
|
variableDeclarationName
|
||||||
] as SketchGroup
|
) as SketchGroup
|
||||||
const sgPaths = sketchGroup.value
|
const sgPaths = sketchGroup.value
|
||||||
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
||||||
|
|
||||||
@ -1081,9 +1080,9 @@ export class SceneEntities {
|
|||||||
})
|
})
|
||||||
this.sceneProgramMemory = programMemory
|
this.sceneProgramMemory = programMemory
|
||||||
|
|
||||||
const maybeSketchGroup = programMemory.root[variableDeclarationName]
|
const maybeSketchGroup = programMemory.get(variableDeclarationName)
|
||||||
let sketchGroup = undefined
|
let sketchGroup = undefined
|
||||||
if (maybeSketchGroup.type === 'SketchGroup') {
|
if (maybeSketchGroup?.type === 'SketchGroup') {
|
||||||
sketchGroup = maybeSketchGroup
|
sketchGroup = maybeSketchGroup
|
||||||
} else if ((maybeSketchGroup as ExtrudeGroup).sketchGroup) {
|
} else if ((maybeSketchGroup as ExtrudeGroup).sketchGroup) {
|
||||||
sketchGroup = (maybeSketchGroup as ExtrudeGroup).sketchGroup
|
sketchGroup = (maybeSketchGroup as ExtrudeGroup).sketchGroup
|
||||||
@ -1773,7 +1772,7 @@ function prepareTruncatedMemoryAndAst(
|
|||||||
if (err(_node)) return _node
|
if (err(_node)) return _node
|
||||||
const variableDeclarationName = _node.node?.declarations?.[0]?.id?.name || ''
|
const variableDeclarationName = _node.node?.declarations?.[0]?.id?.name || ''
|
||||||
const lastSeg = (
|
const lastSeg = (
|
||||||
programMemory.root[variableDeclarationName] as SketchGroup
|
programMemory.get(variableDeclarationName) as SketchGroup
|
||||||
).value.slice(-1)[0]
|
).value.slice(-1)[0]
|
||||||
if (draftSegment) {
|
if (draftSegment) {
|
||||||
// truncatedAst needs to setup with another segment at the end
|
// truncatedAst needs to setup with another segment at the end
|
||||||
@ -1824,33 +1823,27 @@ function prepareTruncatedMemoryAndAst(
|
|||||||
..._ast,
|
..._ast,
|
||||||
body: [JSON.parse(JSON.stringify(_ast.body[bodyIndex]))],
|
body: [JSON.parse(JSON.stringify(_ast.body[bodyIndex]))],
|
||||||
}
|
}
|
||||||
const programMemoryOverride = programMemoryInit()
|
|
||||||
if (err(programMemoryOverride)) return programMemoryOverride
|
|
||||||
|
|
||||||
// Grab all the TagDeclarators and TagIdentifiers from memory.
|
// Grab all the TagDeclarators and TagIdentifiers from memory.
|
||||||
let start = _node.node.start
|
let start = _node.node.start
|
||||||
for (const key in programMemory.root) {
|
const programMemoryOverride = programMemory.filterVariables(true, (value) => {
|
||||||
const value = programMemory.root[key]
|
|
||||||
if (!('__meta' in value)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if (
|
if (
|
||||||
|
!('__meta' in value) ||
|
||||||
value.__meta === undefined ||
|
value.__meta === undefined ||
|
||||||
value.__meta.length === 0 ||
|
value.__meta.length === 0 ||
|
||||||
value.__meta[0].sourceRange === undefined
|
value.__meta[0].sourceRange === undefined
|
||||||
) {
|
) {
|
||||||
continue
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.__meta[0].sourceRange[0] >= start) {
|
if (value.__meta[0].sourceRange[0] >= start) {
|
||||||
// We only want things before our start point.
|
// We only want things before our start point.
|
||||||
continue
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.type === 'TagIdentifier') {
|
return value.type === 'TagIdentifier'
|
||||||
programMemoryOverride.root[key] = JSON.parse(JSON.stringify(value))
|
})
|
||||||
}
|
if (err(programMemoryOverride)) return programMemoryOverride
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < bodyIndex; i++) {
|
for (let i = 0; i < bodyIndex; i++) {
|
||||||
const node = _ast.body[i]
|
const node = _ast.body[i]
|
||||||
@ -1858,12 +1851,15 @@ function prepareTruncatedMemoryAndAst(
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
const name = node.declarations[0].id.name
|
const name = node.declarations[0].id.name
|
||||||
// const memoryItem = kclManager.programMemory.root[name]
|
const memoryItem = programMemory.get(name)
|
||||||
const memoryItem = programMemory.root[name]
|
|
||||||
if (!memoryItem) {
|
if (!memoryItem) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
programMemoryOverride.root[name] = JSON.parse(JSON.stringify(memoryItem))
|
const error = programMemoryOverride.set(
|
||||||
|
name,
|
||||||
|
JSON.parse(JSON.stringify(memoryItem))
|
||||||
|
)
|
||||||
|
if (err(error)) return error
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
truncatedAst,
|
truncatedAst,
|
||||||
@ -1900,7 +1896,7 @@ export function sketchGroupFromPathToNode({
|
|||||||
)
|
)
|
||||||
if (err(_varDec)) return _varDec
|
if (err(_varDec)) return _varDec
|
||||||
const varDec = _varDec.node
|
const varDec = _varDec.node
|
||||||
const result = programMemory.root[varDec?.id?.name || '']
|
const result = programMemory.get(varDec?.id?.name || '')
|
||||||
if (result?.type === 'ExtrudeGroup') {
|
if (result?.type === 'ExtrudeGroup') {
|
||||||
return result.sketchGroup
|
return result.sketchGroup
|
||||||
}
|
}
|
||||||
|
@ -49,9 +49,9 @@ export const AppHeader = ({
|
|||||||
<>
|
<>
|
||||||
<CommandBarOpenButton />
|
<CommandBarOpenButton />
|
||||||
<RefreshButton />
|
<RefreshButton />
|
||||||
<UserSidebarMenu user={user} />
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
<UserSidebarMenu user={user} />
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
)
|
)
|
||||||
|