Compare commits
23 Commits
v0.24.2
...
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 |
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
|
37
README.md
@ -124,28 +124,39 @@ 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. Smoke test the artifact from the above 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.
|
||||||
We don't have a strict process, but click around and check for anything obvious
|
|
||||||
One of the artifacts is called 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 v0.99.99, install it and check that the app comes back at that version (on both macOS and Windows).
|
#### 2. Smoke test artifacts from the Cut Release PR
|
||||||
|
|
||||||
3. Merge the 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. Profit (A new Action kicks in at https://github.com/KittyCAD/modeling-app/actions if the PR was correctly named)
|
#### 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.
|
||||||
|
|
||||||
|
|
||||||
## Fuzzing the parser
|
## Fuzzing the parser
|
||||||
|
@ -7221,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: 44 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: 44 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 33 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.2",
|
"version": "0.24.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/autocomplete": "^6.17.0",
|
"@codemirror/autocomplete": "^6.17.0",
|
||||||
|
108
src-tauri/Cargo.lock
generated
@ -332,7 +332,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -367,7 +367,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -407,7 +407,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"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.70",
|
"syn 2.0.71",
|
||||||
"syn_derive",
|
"syn_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -823,7 +823,7 @@ dependencies = [
|
|||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"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.70",
|
"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.70",
|
"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.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1118,7 +1118,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1179,7 +1179,7 @@ checksum = "4078275de501a61ceb9e759d37bdd3d7210e654dbc167ac1a3678ef4435ed57b"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1216,7 +1216,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_tokenstream",
|
"serde_tokenstream",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1227,7 +1227,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1288,7 +1288,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1320,7 +1320,7 @@ checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1427,7 +1427,7 @@ checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1588,7 +1588,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1704,7 +1704,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"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.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2008,7 +2008,7 @@ dependencies = [
|
|||||||
"inflections",
|
"inflections",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"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.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3377,7 +3377,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"regex-syntax 0.8.3",
|
"regex-syntax 0.8.3",
|
||||||
"structmeta",
|
"structmeta",
|
||||||
"syn 2.0.70",
|
"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.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3564,7 +3564,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"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.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4558,7 +4558,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4569,7 +4569,7 @@ checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4602,7 +4602,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4623,7 +4623,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"serde",
|
"serde",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4665,7 +4665,7 @@ dependencies = [
|
|||||||
"darling",
|
"darling",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4933,7 +4933,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"structmeta-derive",
|
"structmeta-derive",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4944,7 +4944,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4966,7 +4966,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4999,9 +4999,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.70"
|
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 = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16"
|
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.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -5034,7 +5034,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -5251,7 +5251,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
"syn 2.0.70",
|
"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.70",
|
"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.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -5740,7 +5740,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -5940,7 +5940,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -5969,7 +5969,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6099,7 +6099,7 @@ checksum = "c88cc88fd23b5a04528f3a8436024f20010a16ec18eb23c164b1242f65860130"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -6316,7 +6316,7 @@ dependencies = [
|
|||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6415,7 +6415,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"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.70",
|
"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.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6696,7 +6696,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6707,7 +6707,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -7159,7 +7159,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.70",
|
"syn 2.0.71",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -80,5 +80,5 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"productName": "Zoo Modeling App",
|
"productName": "Zoo Modeling App",
|
||||||
"version": "0.24.2"
|
"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()
|
||||||
|
@ -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>
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useState, useRef } from 'react'
|
import { useEffect, useState, useRef } from 'react'
|
||||||
import { parse, BinaryPart, Value } from '../lang/wasm'
|
import { parse, BinaryPart, Value, ProgramMemory } from '../lang/wasm'
|
||||||
import {
|
import {
|
||||||
createIdentifier,
|
createIdentifier,
|
||||||
createLiteral,
|
createLiteral,
|
||||||
@ -120,8 +120,7 @@ export function useCalc({
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const allVarNames = Object.keys(programMemory.root)
|
if (programMemory.has(newVariableName)) {
|
||||||
if (allVarNames.includes(newVariableName)) {
|
|
||||||
setIsNewVariableNameUnique(false)
|
setIsNewVariableNameUnique(false)
|
||||||
} else {
|
} else {
|
||||||
setIsNewVariableNameUnique(true)
|
setIsNewVariableNameUnique(true)
|
||||||
@ -143,17 +142,20 @@ export function useCalc({
|
|||||||
const code = `const __result__ = ${value}`
|
const code = `const __result__ = ${value}`
|
||||||
const ast = parse(code)
|
const ast = parse(code)
|
||||||
if (trap(ast)) return
|
if (trap(ast)) return
|
||||||
const _programMem: any = { root: {}, return: null }
|
const _programMem: ProgramMemory = ProgramMemory.empty()
|
||||||
availableVarInfo.variables.forEach(({ key, value }) => {
|
for (const { key, value } of availableVarInfo.variables) {
|
||||||
_programMem.root[key] = { type: 'userVal', value, __meta: [] }
|
const error = _programMem.set(key, {
|
||||||
})
|
type: 'UserVal',
|
||||||
|
value,
|
||||||
|
__meta: [],
|
||||||
|
})
|
||||||
|
if (trap(error)) return
|
||||||
|
}
|
||||||
executeAst({
|
executeAst({
|
||||||
ast,
|
ast,
|
||||||
engineCommandManager,
|
engineCommandManager,
|
||||||
useFakeExecutor: true,
|
useFakeExecutor: true,
|
||||||
programMemoryOverride: JSON.parse(
|
programMemoryOverride: kclManager.programMemory.clone(),
|
||||||
JSON.stringify(kclManager.programMemory)
|
|
||||||
),
|
|
||||||
}).then(({ programMemory }) => {
|
}).then(({ programMemory }) => {
|
||||||
const resultDeclaration = ast.body.find(
|
const resultDeclaration = ast.body.find(
|
||||||
(a) =>
|
(a) =>
|
||||||
@ -163,7 +165,7 @@ export function useCalc({
|
|||||||
const init =
|
const init =
|
||||||
resultDeclaration?.type === 'VariableDeclaration' &&
|
resultDeclaration?.type === 'VariableDeclaration' &&
|
||||||
resultDeclaration?.declarations?.[0]?.init
|
resultDeclaration?.declarations?.[0]?.init
|
||||||
const result = programMemory?.root?.__result__?.value
|
const result = programMemory?.get('__result__')?.value
|
||||||
setCalcResult(typeof result === 'number' ? String(result) : 'NAN')
|
setCalcResult(typeof result === 'number' ? String(result) : 'NAN')
|
||||||
init && setValueNode(init)
|
init && setValueNode(init)
|
||||||
})
|
})
|
||||||
|
@ -311,6 +311,16 @@ const CustomIconMap = {
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
),
|
),
|
||||||
|
link: (
|
||||||
|
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M10.5864 4.46513C11.9532 3.09829 14.1693 3.09829 15.5361 4.46513C16.903 5.83196 16.903 8.04804 15.5361 9.41488L13.5364 11.4147C13.5839 10.9639 13.5635 10.5074 13.4752 10.0616L14.829 8.70777C15.8053 7.73146 15.8053 6.14855 14.829 5.17224C13.8527 4.19592 12.2698 4.19592 11.2935 5.17224L9.17217 7.29356C8.19586 8.26987 8.19586 9.85278 9.17217 10.8291C9.53458 11.1915 9.98056 11.4194 10.4481 11.5127C10.3749 11.6902 10.2662 11.8565 10.122 12.0007L9.76392 12.3587C9.28973 12.1899 8.84465 11.9158 8.46507 11.5362C7.09823 10.1694 7.09823 7.95328 8.46507 6.58645L10.5864 4.46513ZM4.46507 10.5864L6.46488 8.58663C6.41734 9.03738 6.43772 9.49394 6.52601 9.93972L5.17217 11.2935C4.19586 12.2699 4.19586 13.8528 5.17217 14.8291C6.14849 15.8054 7.7314 15.8054 8.70771 14.8291L10.829 12.7078C11.8053 11.7315 11.8053 10.1485 10.829 9.17223C10.4666 8.80983 10.0207 8.58195 9.55314 8.48859C9.62635 8.31113 9.73506 8.14487 9.87926 8.00066L10.2373 7.64262C10.7115 7.81138 11.1566 8.08555 11.5361 8.46512C12.903 9.83196 12.903 12.048 11.5361 13.4149L9.41481 15.5362C8.04798 16.903 5.8319 16.903 4.46507 15.5362C3.09823 14.1694 3.09823 11.9533 4.46507 10.5864Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
'make-variable': (
|
'make-variable': (
|
||||||
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path
|
<path
|
||||||
|
@ -131,6 +131,9 @@ export const ModelingMachineProvider = ({
|
|||||||
},
|
},
|
||||||
'sketch exit execute': ({ store }) => {
|
'sketch exit execute': ({ store }) => {
|
||||||
;(async () => {
|
;(async () => {
|
||||||
|
// blocks entering a sketch until after exit sketch code has run
|
||||||
|
kclManager.isExecuting = true
|
||||||
|
|
||||||
await sceneInfra.camControls.snapToPerspectiveBeforeHandingBackControlToEngine()
|
await sceneInfra.camControls.snapToPerspectiveBeforeHandingBackControlToEngine()
|
||||||
|
|
||||||
sceneInfra.camControls.syncDirection = 'engineToClient'
|
sceneInfra.camControls.syncDirection = 'engineToClient'
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import styles from './ModelingPane.module.css'
|
import styles from './ModelingPane.module.css'
|
||||||
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
|
import { ActionButton } from 'components/ActionButton'
|
||||||
|
import Tooltip from 'components/Tooltip'
|
||||||
|
|
||||||
export interface ModelingPaneProps
|
export interface ModelingPaneProps
|
||||||
extends React.PropsWithChildren,
|
extends React.PropsWithChildren,
|
||||||
@ -8,16 +10,32 @@ export interface ModelingPaneProps
|
|||||||
title: string
|
title: string
|
||||||
Menu?: React.ReactNode | React.FC
|
Menu?: React.ReactNode | React.FC
|
||||||
detailsTestId?: string
|
detailsTestId?: string
|
||||||
|
onClose: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ModelingPaneHeader = ({
|
export const ModelingPaneHeader = ({
|
||||||
title,
|
title,
|
||||||
Menu,
|
Menu,
|
||||||
}: Pick<ModelingPaneProps, 'title' | 'Menu'>) => {
|
onClose,
|
||||||
|
}: Pick<ModelingPaneProps, 'title' | 'Menu' | 'onClose'>) => {
|
||||||
return (
|
return (
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<div className="flex gap-2 items-center flex-1">{title}</div>
|
<div className="flex gap-2 items-center flex-1">{title}</div>
|
||||||
{Menu instanceof Function ? <Menu /> : Menu}
|
{Menu instanceof Function ? <Menu /> : Menu}
|
||||||
|
<ActionButton
|
||||||
|
Element="button"
|
||||||
|
iconStart={{
|
||||||
|
icon: 'close',
|
||||||
|
iconClassName: '!text-current',
|
||||||
|
bgClassName: 'bg-transparent dark:bg-transparent',
|
||||||
|
}}
|
||||||
|
className="!p-0 !bg-transparent hover:text-primary border-transparent dark:!border-transparent hover:!border-primary dark:hover:!border-chalkboard-70 !outline-none"
|
||||||
|
onClick={onClose}
|
||||||
|
>
|
||||||
|
<Tooltip position="bottom-right" delay={750}>
|
||||||
|
Close
|
||||||
|
</Tooltip>
|
||||||
|
</ActionButton>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -29,6 +47,7 @@ export const ModelingPane = ({
|
|||||||
className,
|
className,
|
||||||
Menu,
|
Menu,
|
||||||
detailsTestId,
|
detailsTestId,
|
||||||
|
onClose,
|
||||||
...props
|
...props
|
||||||
}: ModelingPaneProps) => {
|
}: ModelingPaneProps) => {
|
||||||
const { settings } = useSettingsAuthContext()
|
const { settings } = useSettingsAuthContext()
|
||||||
@ -51,7 +70,7 @@ export const ModelingPane = ({
|
|||||||
(className || '')
|
(className || '')
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<ModelingPaneHeader title={title} Menu={Menu} />
|
<ModelingPaneHeader title={title} Menu={Menu} onClose={onClose} />
|
||||||
<div className="relative w-full">{children}</div>
|
<div className="relative w-full">{children}</div>
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
|
@ -163,7 +163,7 @@ export function useCodeMirror(props: UseCodeMirror) {
|
|||||||
effects: StateEffect.reconfigure.of(targetExtensions),
|
effects: StateEffect.reconfigure.of(targetExtensions),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, [targetExtensions])
|
}, [targetExtensions, view, isFirstRender])
|
||||||
|
|
||||||
return { view, setView, container, setContainer, state, setState }
|
return { view, setView, container, setContainer, state, setState }
|
||||||
}
|
}
|
||||||
|
@ -24,14 +24,12 @@ export const KclEditorMenu = ({ children }: PropsWithChildren) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Menu.Button className="p-0 border-none relative">
|
<Menu.Button className="!p-0 !bg-transparent hover:text-primary border-transparent dark:!border-transparent hover:!border-primary dark:hover:!border-chalkboard-70 ui-open:!border-primary dark:ui-open:!border-chalkboard-70 !outline-none">
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
icon="three-dots"
|
icon="three-dots"
|
||||||
className="p-1"
|
className="p-1"
|
||||||
size="sm"
|
size="sm"
|
||||||
bgClassName={
|
bgClassName="bg-transparent dark:bg-transparent"
|
||||||
'!bg-transparent hover:!bg-primary/10 hover:dark:!bg-chalkboard-100 ui-open:!bg-primary/10 dark:ui-open:!bg-chalkboard-100 rounded-sm'
|
|
||||||
}
|
|
||||||
iconClassName={'!text-chalkboard-90 dark:!text-chalkboard-40'}
|
iconClassName={'!text-chalkboard-90 dark:!text-chalkboard-40'}
|
||||||
/>
|
/>
|
||||||
</Menu.Button>
|
</Menu.Button>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { processMemory } from './MemoryPane'
|
import { processMemory } from './MemoryPane'
|
||||||
import { enginelessExecutor } from '../../../lib/testHelpers'
|
import { enginelessExecutor } from '../../../lib/testHelpers'
|
||||||
import { initPromise, parse } from '../../../lang/wasm'
|
import { initPromise, parse, ProgramMemory } from '../../../lang/wasm'
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await initPromise
|
await initPromise
|
||||||
@ -29,10 +29,7 @@ describe('processMemory', () => {
|
|||||||
|> lineTo([2.15, 4.32], %)
|
|> lineTo([2.15, 4.32], %)
|
||||||
// |> rx(90, %)`
|
// |> rx(90, %)`
|
||||||
const ast = parse(code)
|
const ast = parse(code)
|
||||||
const programMemory = await enginelessExecutor(ast, {
|
const programMemory = await enginelessExecutor(ast, ProgramMemory.empty())
|
||||||
root: {},
|
|
||||||
return: null,
|
|
||||||
})
|
|
||||||
const output = processMemory(programMemory)
|
const output = processMemory(programMemory)
|
||||||
expect(output.myVar).toEqual(5)
|
expect(output.myVar).toEqual(5)
|
||||||
expect(output.otherVar).toEqual(3)
|
expect(output.otherVar).toEqual(3)
|
||||||
|
@ -82,8 +82,7 @@ export const MemoryPane = () => {
|
|||||||
|
|
||||||
export const processMemory = (programMemory: ProgramMemory) => {
|
export const processMemory = (programMemory: ProgramMemory) => {
|
||||||
const processedMemory: any = {}
|
const processedMemory: any = {}
|
||||||
Object.keys(programMemory?.root || {}).forEach((key) => {
|
for (const [key, val] of programMemory?.visibleEntries()) {
|
||||||
const val = programMemory.root[key]
|
|
||||||
if (typeof val.value !== 'function') {
|
if (typeof val.value !== 'function') {
|
||||||
if (val.type === 'SketchGroup') {
|
if (val.type === 'SketchGroup') {
|
||||||
processedMemory[key] = val.value.map(({ __geoMeta, ...rest }: Path) => {
|
processedMemory[key] = val.value.map(({ __geoMeta, ...rest }: Path) => {
|
||||||
@ -103,6 +102,6 @@ export const processMemory = (programMemory: ProgramMemory) => {
|
|||||||
} else if (key !== 'log') {
|
} else if (key !== 'log') {
|
||||||
processedMemory[key] = '__function__'
|
processedMemory[key] = '__function__'
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
return processedMemory
|
return processedMemory
|
||||||
}
|
}
|
||||||
|
@ -204,6 +204,7 @@ function ModelingSidebarSection({
|
|||||||
id={`${pane.id}-pane`}
|
id={`${pane.id}-pane`}
|
||||||
title={pane.title}
|
title={pane.title}
|
||||||
Menu={pane.Menu}
|
Menu={pane.Menu}
|
||||||
|
onClose={() => togglePane(pane.id)}
|
||||||
>
|
>
|
||||||
{pane.Content instanceof Function ? (
|
{pane.Content instanceof Function ? (
|
||||||
<pane.Content />
|
<pane.Content />
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Popover, Transition } from '@headlessui/react'
|
import { Popover, Transition } from '@headlessui/react'
|
||||||
import { ActionButton } from './ActionButton'
|
import { ActionButton, ActionButtonProps } from './ActionButton'
|
||||||
import { type IndexLoaderData } from 'lib/types'
|
import { type IndexLoaderData } from 'lib/types'
|
||||||
import { paths } from 'lib/paths'
|
import { paths } from 'lib/paths'
|
||||||
import { isTauri } from '../lib/isTauri'
|
import { isTauri } from '../lib/isTauri'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link, useLocation, useNavigate } from 'react-router-dom'
|
||||||
import { Fragment } from 'react'
|
import { Fragment, useMemo } from 'react'
|
||||||
import { sep } from '@tauri-apps/api/path'
|
import { sep } from '@tauri-apps/api/path'
|
||||||
import { Logo } from './Logo'
|
import { Logo } from './Logo'
|
||||||
import { APP_NAME } from 'lib/constants'
|
import { APP_NAME } from 'lib/constants'
|
||||||
@ -12,6 +12,9 @@ import { useCommandsContext } from 'hooks/useCommandsContext'
|
|||||||
import { CustomIcon } from './CustomIcon'
|
import { CustomIcon } from './CustomIcon'
|
||||||
import { useLspContext } from './LspProvider'
|
import { useLspContext } from './LspProvider'
|
||||||
import { engineCommandManager } from 'lib/singletons'
|
import { engineCommandManager } from 'lib/singletons'
|
||||||
|
import usePlatform from 'hooks/usePlatform'
|
||||||
|
import { useAbsoluteFilePath } from 'hooks/useAbsoluteFilePath'
|
||||||
|
import Tooltip from './Tooltip'
|
||||||
|
|
||||||
const ProjectSidebarMenu = ({
|
const ProjectSidebarMenu = ({
|
||||||
project,
|
project,
|
||||||
@ -80,6 +83,10 @@ function ProjectMenuPopover({
|
|||||||
project?: IndexLoaderData['project']
|
project?: IndexLoaderData['project']
|
||||||
file?: IndexLoaderData['file']
|
file?: IndexLoaderData['file']
|
||||||
}) {
|
}) {
|
||||||
|
const platform = usePlatform()
|
||||||
|
const location = useLocation()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const filePath = useAbsoluteFilePath()
|
||||||
const { commandBarState, commandBarSend } = useCommandsContext()
|
const { commandBarState, commandBarSend } = useCommandsContext()
|
||||||
const { onProjectClose } = useLspContext()
|
const { onProjectClose } = useLspContext()
|
||||||
const exportCommandInfo = { name: 'Export', groupId: 'modeling' }
|
const exportCommandInfo = { name: 'Export', groupId: 'modeling' }
|
||||||
@ -90,13 +97,82 @@ function ProjectMenuPopover({
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// We filter this memoized list so that no orphan "break" elements are rendered.
|
||||||
|
const projectMenuItems = useMemo<(ActionButtonProps | 'break')[]>(
|
||||||
|
() =>
|
||||||
|
[
|
||||||
|
{
|
||||||
|
id: 'settings',
|
||||||
|
Element: 'button',
|
||||||
|
children: (
|
||||||
|
<>
|
||||||
|
<span className="flex-1">Project settings</span>
|
||||||
|
<kbd className="hotkey">{`${platform === 'macos' ? '⌘' : 'Ctrl'}${
|
||||||
|
isTauri() ? '' : '⬆'
|
||||||
|
},`}</kbd>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
onClick: () => {
|
||||||
|
const targetPath = location.pathname.includes(paths.FILE)
|
||||||
|
? filePath + paths.SETTINGS
|
||||||
|
: paths.HOME + paths.SETTINGS
|
||||||
|
navigate(targetPath + '?tab=project')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'break',
|
||||||
|
{
|
||||||
|
id: 'export',
|
||||||
|
Element: 'button',
|
||||||
|
children: (
|
||||||
|
<>
|
||||||
|
<span>Export current part</span>
|
||||||
|
{!findCommand(exportCommandInfo) && (
|
||||||
|
<Tooltip position="right" className="!max-w-none min-w-fit">
|
||||||
|
Awaiting engine connection
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
disabled: !findCommand(exportCommandInfo),
|
||||||
|
onClick: () =>
|
||||||
|
commandBarSend({
|
||||||
|
type: 'Find and select command',
|
||||||
|
data: exportCommandInfo,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
'break',
|
||||||
|
{
|
||||||
|
id: 'go-home',
|
||||||
|
Element: 'button',
|
||||||
|
children: 'Go to Home',
|
||||||
|
className: !isTauri() ? 'hidden' : '',
|
||||||
|
onClick: () => {
|
||||||
|
onProjectClose(file || null, project?.path || null, true)
|
||||||
|
// Clear the scene and end the session.
|
||||||
|
engineCommandManager.endSession()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
].filter(
|
||||||
|
(props) =>
|
||||||
|
props === 'break' ||
|
||||||
|
(typeof props !== 'string' && !props.className?.includes('hidden'))
|
||||||
|
) as (ActionButtonProps | 'break')[],
|
||||||
|
[
|
||||||
|
platform,
|
||||||
|
findCommand,
|
||||||
|
commandBarSend,
|
||||||
|
engineCommandManager,
|
||||||
|
onProjectClose,
|
||||||
|
isTauri,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover className="relative">
|
<Popover className="relative">
|
||||||
<Popover.Button
|
<Popover.Button
|
||||||
className="rounded-sm h-9 mr-auto max-h-min min-w-max border-0 py-1 pl-0 pr-2 flex items-center focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary dark:hover:bg-chalkboard-90"
|
className="gap-1 rounded-sm h-9 mr-auto max-h-min min-w-max border-0 py-1 px-2 flex items-center focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary dark:hover:bg-chalkboard-90"
|
||||||
data-testid="project-sidebar-toggle"
|
data-testid="project-sidebar-toggle"
|
||||||
>
|
>
|
||||||
<CustomIcon name="three-dots" className="w-5 h-5 rotate-90" />
|
|
||||||
<div className="flex flex-col items-start py-0.5">
|
<div className="flex flex-col items-start py-0.5">
|
||||||
<span className="hidden text-sm text-chalkboard-110 dark:text-chalkboard-20 whitespace-nowrap lg:block">
|
<span className="hidden text-sm text-chalkboard-110 dark:text-chalkboard-20 whitespace-nowrap lg:block">
|
||||||
{isTauri() && file?.name
|
{isTauri() && file?.name
|
||||||
@ -109,68 +185,53 @@ function ProjectMenuPopover({
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
<CustomIcon
|
||||||
|
name="caretDown"
|
||||||
|
className="w-4 h-4 text-chalkboard-70 dark:text-chalkboard-40 ui-open:rotate-180"
|
||||||
|
/>
|
||||||
</Popover.Button>
|
</Popover.Button>
|
||||||
<Transition
|
|
||||||
enter="duration-200 ease-out"
|
|
||||||
enterFrom="opacity-0"
|
|
||||||
enterTo="opacity-100"
|
|
||||||
leave="duration-100 ease-in"
|
|
||||||
leaveFrom="opacity-100"
|
|
||||||
leaveTo="opacity-0"
|
|
||||||
as={Fragment}
|
|
||||||
>
|
|
||||||
<Popover.Overlay className="fixed inset-0 z-20 bg-chalkboard-110/50" />
|
|
||||||
</Transition>
|
|
||||||
|
|
||||||
<Transition
|
<Transition
|
||||||
enter="duration-100 ease-out"
|
enter="duration-100 ease-out"
|
||||||
enterFrom="opacity-0 -translate-x-1/4"
|
enterFrom="opacity-0 -translate-y-2"
|
||||||
enterTo="opacity-100 translate-x-0"
|
enterTo="opacity-100 translate-y-0"
|
||||||
leave="duration-75 ease-in"
|
|
||||||
leaveFrom="opacity-100 translate-x-0"
|
|
||||||
leaveTo="opacity-0 -translate-x-4"
|
|
||||||
as={Fragment}
|
as={Fragment}
|
||||||
>
|
>
|
||||||
<Popover.Panel
|
<Popover.Panel
|
||||||
className="fixed inset-0 right-auto z-30 grid w-64 h-screen max-h-screen grid-cols-1 border rounded-r-md shadow-md bg-chalkboard-10 dark:bg-chalkboard-100 border-chalkboard-40 dark:border-chalkboard-80"
|
className={`z-10 absolute top-full left-0 mt-1 pb-1 w-48 bg-chalkboard-10 dark:bg-chalkboard-90
|
||||||
style={{ gridTemplateRows: 'auto 1fr auto' }}
|
border border-solid border-chalkboard-20 dark:border-chalkboard-90 rounded
|
||||||
|
shadow-lg`}
|
||||||
>
|
>
|
||||||
{({ close }) => (
|
{({ close }) => (
|
||||||
<>
|
<ul className="relative flex flex-col items-stretch content-stretch p-0.5">
|
||||||
<div className="flex flex-col gap-2 p-4">
|
{projectMenuItems.map((props, index) => {
|
||||||
<ActionButton
|
if (props === 'break') {
|
||||||
Element="button"
|
return index !== projectMenuItems.length - 1 ? (
|
||||||
iconStart={{ icon: 'exportFile', className: 'p-1' }}
|
<li key={`break-${index}`} className="contents">
|
||||||
className="border-transparent dark:border-transparent"
|
<hr className="border-chalkboard-20 dark:border-chalkboard-80" />
|
||||||
disabled={!findCommand(exportCommandInfo)}
|
</li>
|
||||||
onClick={() =>
|
) : null
|
||||||
commandBarSend({
|
}
|
||||||
type: 'Find and select command',
|
|
||||||
data: exportCommandInfo,
|
const { id, className, children, ...rest } = props
|
||||||
})
|
return (
|
||||||
}
|
<li key={id} className="contents">
|
||||||
>
|
<ActionButton
|
||||||
Export Part
|
{...rest}
|
||||||
</ActionButton>
|
className={
|
||||||
{isTauri() && (
|
'relative !font-sans flex items-center gap-2 rounded-sm py-1.5 px-2 cursor-pointer hover:bg-chalkboard-20 dark:hover:bg-chalkboard-80 border-none text-left ' +
|
||||||
<ActionButton
|
className
|
||||||
Element="button"
|
}
|
||||||
onClick={() => {
|
onMouseUp={() => {
|
||||||
onProjectClose(file || null, project?.path || null, true)
|
close()
|
||||||
// Clear the scene and end the session.
|
}}
|
||||||
engineCommandManager.endSession()
|
>
|
||||||
}}
|
{children}
|
||||||
iconStart={{
|
</ActionButton>
|
||||||
icon: 'arrowLeft',
|
</li>
|
||||||
className: 'p-1',
|
)
|
||||||
}}
|
})}
|
||||||
className="border-transparent dark:border-transparent"
|
</ul>
|
||||||
>
|
|
||||||
Go to Home
|
|
||||||
</ActionButton>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
</Popover.Panel>
|
</Popover.Panel>
|
||||||
</Transition>
|
</Transition>
|
||||||
|
@ -157,6 +157,7 @@ export const Stream = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsFirstRender(kclManager.isFirstRender)
|
setIsFirstRender(kclManager.isFirstRender)
|
||||||
if (!kclManager.isFirstRender) videoRef.current?.play()
|
if (!kclManager.isFirstRender) videoRef.current?.play()
|
||||||
|
setIsFreezeFrame(!kclManager.isFirstRender)
|
||||||
}, [kclManager.isFirstRender])
|
}, [kclManager.isFirstRender])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -178,6 +179,8 @@ export const Stream = () => {
|
|||||||
videoElement: videoRef.current,
|
videoElement: videoRef.current,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
setIsLoading(false)
|
||||||
}, [mediaStream])
|
}, [mediaStream])
|
||||||
|
|
||||||
const handleMouseDown: MouseEventHandler<HTMLDivElement> = (e) => {
|
const handleMouseDown: MouseEventHandler<HTMLDivElement> = (e) => {
|
||||||
|
@ -8,7 +8,9 @@
|
|||||||
--_delay: 200ms;
|
--_delay: 200ms;
|
||||||
--_triangle-width: 8px;
|
--_triangle-width: 8px;
|
||||||
--_triangle-height: 12px;
|
--_triangle-height: 12px;
|
||||||
--_p-inline: calc(50% + calc(var(--isRTL) * var(--_triangle-width) / 2));
|
--_p-inline-arrow-alignment: calc(
|
||||||
|
50% + calc(var(--isRTL) * var(--_triangle-width) / 2)
|
||||||
|
);
|
||||||
--_p-block: 4px;
|
--_p-block: 4px;
|
||||||
--_bg: var(--chalkboard-10);
|
--_bg: var(--chalkboard-10);
|
||||||
--_shadow-alpha: 8%;
|
--_shadow-alpha: 8%;
|
||||||
@ -33,7 +35,7 @@
|
|||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
line-height: initial;
|
line-height: initial;
|
||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
padding: var(--_p-block) var(--_p-inline);
|
padding: var(--_p-block) calc(2 * var(--_p-block));
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
background: var(--_bg);
|
background: var(--_bg);
|
||||||
@ -119,7 +121,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tooltip.top-right {
|
.tooltip.top-right {
|
||||||
inset-inline-end: var(--_p-inline);
|
inset-inline-end: var(--_p-inline-arrow-alignment);
|
||||||
inset-block-end: calc(100% + var(--_p-block) + var(--_triangle-height));
|
inset-block-end: calc(100% + var(--_p-block) + var(--_triangle-height));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +132,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tooltip.right {
|
.tooltip.right {
|
||||||
inset-inline-start: calc(100% + var(--_p-inline) + var(--_triangle-height));
|
inset-inline-start: calc(100% + var(--_triangle-height));
|
||||||
inset-block-end: 50%;
|
inset-block-end: 50%;
|
||||||
--_y: 50%;
|
--_y: 50%;
|
||||||
}
|
}
|
||||||
@ -142,7 +144,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tooltip.bottom-right {
|
.tooltip.bottom-right {
|
||||||
inset-inline-end: var(--_p-inline);
|
inset-inline-end: var(--_p-inline-arrow-alignment);
|
||||||
inset-block-start: calc(100% + var(--_p-block) + var(--_triangle-height));
|
inset-block-start: calc(100% + var(--_p-block) + var(--_triangle-height));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +167,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tooltip.bottom-left {
|
.tooltip.bottom-left {
|
||||||
inset-inline-start: var(--_p-inline);
|
inset-inline-start: var(--_p-inline-arrow-alignment);
|
||||||
inset-block-start: calc(100% + var(--_p-block) + var(--_triangle-height));
|
inset-block-start: calc(100% + var(--_p-block) + var(--_triangle-height));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +178,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tooltip.left {
|
.tooltip.left {
|
||||||
inset-inline-end: calc(100% + var(--_p-inline) + var(--_triangle-height));
|
inset-inline-end: calc(
|
||||||
|
100% + var(--_p-inline-arrow-alignment) + var(--_triangle-height)
|
||||||
|
);
|
||||||
inset-block-end: 50%;
|
inset-block-end: 50%;
|
||||||
--_y: 50%;
|
--_y: 50%;
|
||||||
}
|
}
|
||||||
@ -188,7 +192,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tooltip.top-left {
|
.tooltip.top-left {
|
||||||
inset-inline-start: var(--_p-inline);
|
inset-inline-start: var(--_p-inline-arrow-alignment);
|
||||||
inset-block-end: calc(100% + var(--_p-block) + var(--_triangle-height));
|
inset-block-end: calc(100% + var(--_p-block) + var(--_triangle-height));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,11 +25,11 @@ export function UnitsMenu() {
|
|||||||
border border-solid border-chalkboard-10 dark:border-chalkboard-90 rounded
|
border border-solid border-chalkboard-10 dark:border-chalkboard-90 rounded
|
||||||
shadow-lg`}
|
shadow-lg`}
|
||||||
>
|
>
|
||||||
<ul className="relative flex flex-col gap-0.5 items-stretch content-stretch">
|
<ul className="relative flex flex-col items-stretch content-stretch p-0.5">
|
||||||
{baseUnitsUnion.map((unit) => (
|
{baseUnitsUnion.map((unit) => (
|
||||||
<li key={unit} className="contents">
|
<li key={unit} className="contents">
|
||||||
<button
|
<button
|
||||||
className="flex items-center gap-2 py-1 px-2 cursor-pointer hover:bg-chalkboard-20 dark:hover:bg-chalkboard-80 border-none text-left"
|
className="flex items-center gap-2 m-0 py-1.5 px-2 cursor-pointer hover:bg-chalkboard-20 dark:hover:bg-chalkboard-80 border-none text-left"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
settings.send({
|
settings.send({
|
||||||
type: 'set.modeling.defaultUnit',
|
type: 'set.modeling.defaultUnit',
|
||||||
|