From 7da0fcfee91839e4b32bab92e7e2689e1390cd8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Fri, 8 May 2026 14:27:18 +0200 Subject: [PATCH 01/12] chore: initial commit From 8bf251c3d49cce90f9c9e3d57ef88cf9b0b95640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Fri, 8 May 2026 14:32:07 +0200 Subject: [PATCH 02/12] fix: reconciler issues when moving nodes between layers --- code/CHANGELOG.md | 237 +----------------- .../renderer-konva-base/src/reconciler.ts | 6 +- .../renderer-konva-base/src/renderer.ts | 31 ++- .../sdk/src/actions/image-tool/image-tool.ts | 10 +- .../src/actions/images-tool/images-tool.ts | 10 +- .../sdk/src/actions/video-tool/video-tool.ts | 6 +- code/packages/sdk/src/managers/targeting.ts | 57 ++--- .../sdk/src/nodes/connector/connector.ts | 1 - code/packages/sdk/src/nodes/extensions.d.ts | 1 - code/packages/sdk/src/nodes/frame/frame.ts | 1 - code/packages/sdk/src/nodes/group/group.ts | 1 - .../packages/sdk/src/nodes/image/constants.ts | 3 + code/packages/sdk/src/nodes/image/image.ts | 50 ++-- code/packages/sdk/src/nodes/image/types.ts | 3 + code/packages/sdk/src/nodes/layer/layer.ts | 1 - code/packages/sdk/src/nodes/node.ts | 29 ++- code/packages/sdk/src/nodes/stroke/stroke.ts | 1 - code/packages/sdk/src/nodes/text/text.ts | 1 - code/packages/sdk/src/nodes/video/video.ts | 4 + .../nodes-selection/nodes-selection.ts | 14 ++ .../sdk/src/plugins/users-presence/types.ts | 1 + .../plugins/users-presence/users-presence.ts | 20 +- code/packages/sdk/src/utils/utils.ts | 51 +--- code/packages/sdk/src/weave.ts | 5 +- .../content/docs/main/changelog/3.x/3.8.1.mdx | 12 + .../content/docs/main/changelog/3.x/meta.json | 1 + docs/content/docs/main/changelog/index.mdx | 1 + 27 files changed, 165 insertions(+), 393 deletions(-) create mode 100644 docs/content/docs/main/changelog/3.x/3.8.1.mdx diff --git a/code/CHANGELOG.md b/code/CHANGELOG.md index ec4bdacaf..87825a307 100644 --- a/code/CHANGELOG.md +++ b/code/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- [#1044](https://github.com/InditexTech/weavejs/issues/1044) Nodes disappear when moving between frames + ## [3.8.0] - 2026-04-24 ### Added @@ -1763,469 +1767,236 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#18](https://github.com/InditexTech/weavejs/issues/18) Fix awareness not working on store-azure-web-pubsub [Unreleased]: https://github.com/InditexTech/weavejs/compare/3.8.0...HEAD - [3.8.0]: https://github.com/InditexTech/weavejs/compare/3.7.2...3.8.0 - [3.7.2]: https://github.com/InditexTech/weavejs/compare/3.7.1...3.7.2 - [3.7.1]: https://github.com/InditexTech/weavejs/compare/3.7.0...3.7.1 - [3.7.0]: https://github.com/InditexTech/weavejs/compare/3.6.0...3.7.0 - [3.6.0]: https://github.com/InditexTech/weavejs/compare/3.5.0...3.6.0 - [3.5.0]: https://github.com/InditexTech/weavejs/compare/3.4.0...3.5.0 - [3.4.0]: https://github.com/InditexTech/weavejs/compare/3.3.1...3.4.0 - [3.3.1]: https://github.com/InditexTech/weavejs/compare/3.3.0...3.3.1 - [3.3.0]: https://github.com/InditexTech/weavejs/compare/3.2.5...3.3.0 - [3.2.5]: https://github.com/InditexTech/weavejs/compare/3.2.4...3.2.5 - [3.2.4]: https://github.com/InditexTech/weavejs/compare/3.2.3...3.2.4 - [3.2.3]: https://github.com/InditexTech/weavejs/compare/3.2.2...3.2.3 - [3.2.2]: https://github.com/InditexTech/weavejs/compare/3.2.1...3.2.2 - [3.2.1]: https://github.com/InditexTech/weavejs/compare/3.2.0...3.2.1 - [3.2.0]: https://github.com/InditexTech/weavejs/compare/3.1.0...3.2.0 - [3.1.0]: https://github.com/InditexTech/weavejs/compare/3.0.0...3.1.0 - [3.0.0]: https://github.com/InditexTech/weavejs/compare/2.23.0...3.0.0 - [2.23.0]: https://github.com/InditexTech/weavejs/compare/2.22.0...2.23.0 - [2.22.0]: https://github.com/InditexTech/weavejs/compare/2.21.1...2.22.0 - [2.21.1]: https://github.com/InditexTech/weavejs/compare/2.21.0...2.21.1 - [2.21.0]: https://github.com/InditexTech/weavejs/compare/2.20.2...2.21.0 - [2.20.2]: https://github.com/InditexTech/weavejs/compare/2.20.1...2.20.2 - [2.20.1]: https://github.com/InditexTech/weavejs/compare/2.20.0...2.20.1 - [2.20.0]: https://github.com/InditexTech/weavejs/compare/2.19.0...2.20.0 - [2.19.0]: https://github.com/InditexTech/weavejs/compare/2.18.1...2.19.0 - [2.18.1]: https://github.com/InditexTech/weavejs/compare/2.18.0...2.18.1 - [2.18.0]: https://github.com/InditexTech/weavejs/compare/2.17.0...2.18.0 - [2.17.0]: https://github.com/InditexTech/weavejs/compare/2.16.0...2.17.0 - [2.16.0]: https://github.com/InditexTech/weavejs/compare/2.15.3...2.16.0 - [2.15.3]: https://github.com/InditexTech/weavejs/compare/2.15.2...2.15.3 - [2.15.2]: https://github.com/InditexTech/weavejs/compare/2.15.1...2.15.2 - [2.15.1]: https://github.com/InditexTech/weavejs/compare/2.15.0...2.15.1 - [2.15.0]: https://github.com/InditexTech/weavejs/compare/2.14.0...2.15.0 - [2.14.0]: https://github.com/InditexTech/weavejs/compare/2.13.1...2.14.0 - [2.13.1]: https://github.com/InditexTech/weavejs/compare/2.13.0...2.13.1 - [2.13.0]: https://github.com/InditexTech/weavejs/compare/2.12.1...2.13.0 - [2.12.1]: https://github.com/InditexTech/weavejs/compare/2.12.0...2.12.1 - [2.12.0]: https://github.com/InditexTech/weavejs/compare/2.11.1...2.12.0 - [2.11.1]: https://github.com/InditexTech/weavejs/compare/2.11.0...2.11.1 - [2.11.0]: https://github.com/InditexTech/weavejs/compare/2.10.0...2.11.0 - [2.10.0]: https://github.com/InditexTech/weavejs/compare/2.9.5...2.10.0 - [2.9.5]: https://github.com/InditexTech/weavejs/compare/2.9.4...2.9.5 - [2.9.4]: https://github.com/InditexTech/weavejs/compare/2.9.3...2.9.4 - [2.9.3]: https://github.com/InditexTech/weavejs/compare/2.9.2...2.9.3 - [2.9.2]: https://github.com/InditexTech/weavejs/compare/2.9.1...2.9.2 - [2.9.1]: https://github.com/InditexTech/weavejs/compare/2.9.0...2.9.1 - [2.9.0]: https://github.com/InditexTech/weavejs/compare/2.8.1...2.9.0 - [2.8.1]: https://github.com/InditexTech/weavejs/compare/2.8.0...2.8.1 - [2.8.0]: https://github.com/InditexTech/weavejs/compare/2.7.1...2.8.0 - [2.7.1]: https://github.com/InditexTech/weavejs/compare/2.7.0...2.7.1 - [2.7.0]: https://github.com/InditexTech/weavejs/compare/2.6.0...2.7.0 - [2.6.0]: https://github.com/InditexTech/weavejs/compare/2.5.0...2.6.0 - [2.5.0]: https://github.com/InditexTech/weavejs/compare/2.4.0...2.5.0 - [2.4.0]: https://github.com/InditexTech/weavejs/compare/2.3.3...2.4.0 - [2.3.3]: https://github.com/InditexTech/weavejs/compare/2.3.2...2.3.3 - [2.3.2]: https://github.com/InditexTech/weavejs/compare/2.3.1...2.3.2 - [2.3.1]: https://github.com/InditexTech/weavejs/compare/2.3.0...2.3.1 - [2.3.0]: https://github.com/InditexTech/weavejs/compare/2.2.0...2.3.0 - [2.2.0]: https://github.com/InditexTech/weavejs/compare/2.1.1...2.2.0 - [2.1.1]: https://github.com/InditexTech/weavejs/compare/2.1.0...2.1.1 - [2.1.0]: https://github.com/InditexTech/weavejs/compare/2.0.3...2.1.0 - [2.0.3]: https://github.com/InditexTech/weavejs/compare/2.0.2...2.0.3 - [2.0.2]: https://github.com/InditexTech/weavejs/compare/2.0.1...2.0.2 - [2.0.1]: https://github.com/InditexTech/weavejs/compare/2.0.0...2.0.1 - [2.0.0]: https://github.com/InditexTech/weavejs/compare/1.3.0...2.0.0 - [1.3.0]: https://github.com/InditexTech/weavejs/compare/1.2.2...1.3.0 - [1.2.2]: https://github.com/InditexTech/weavejs/compare/1.2.1...1.2.2 - [1.2.1]: https://github.com/InditexTech/weavejs/compare/1.2.0...1.2.1 - [1.2.0]: https://github.com/InditexTech/weavejs/compare/1.1.3...1.2.0 - [1.1.3]: https://github.com/InditexTech/weavejs/compare/1.1.2...1.1.3 - [1.1.2]: https://github.com/InditexTech/weavejs/compare/1.1.1...1.1.2 - [1.1.1]: https://github.com/InditexTech/weavejs/compare/1.1.0...1.1.1 - [1.1.0]: https://github.com/InditexTech/weavejs/compare/1.0.4...1.1.0 - [1.0.4]: https://github.com/InditexTech/weavejs/compare/1.0.3...1.0.4 - [1.0.3]: https://github.com/InditexTech/weavejs/compare/1.0.2...1.0.3 - [1.0.2]: https://github.com/InditexTech/weavejs/compare/1.0.1...1.0.2 - [1.0.1]: https://github.com/InditexTech/weavejs/compare/1.0.0...1.0.1 - [1.0.0]: https://github.com/InditexTech/weavejs/compare/0.77.5...1.0.0 - [0.77.5]: https://github.com/InditexTech/weavejs/compare/0.77.4...0.77.5 - [0.77.4]: https://github.com/InditexTech/weavejs/compare/0.77.3...0.77.4 - [0.77.3]: https://github.com/InditexTech/weavejs/compare/0.77.2...0.77.3 - [0.77.2]: https://github.com/InditexTech/weavejs/compare/0.77.1...0.77.2 - [0.77.1]: https://github.com/InditexTech/weavejs/compare/0.77.0...0.77.1 - [0.77.0]: https://github.com/InditexTech/weavejs/compare/0.76.3...0.77.0 - [0.76.3]: https://github.com/InditexTech/weavejs/compare/0.76.2...0.76.3 - [0.76.2]: https://github.com/InditexTech/weavejs/compare/0.76.1...0.76.2 - [0.76.1]: https://github.com/InditexTech/weavejs/compare/0.76.0...0.76.1 - [0.76.0]: https://github.com/InditexTech/weavejs/compare/0.75.0...0.76.0 - [0.75.0]: https://github.com/InditexTech/weavejs/compare/0.74.3...0.75.0 - [0.74.3]: https://github.com/InditexTech/weavejs/compare/0.74.2...0.74.3 - [0.74.2]: https://github.com/InditexTech/weavejs/compare/0.74.1...0.74.2 - [0.74.1]: https://github.com/InditexTech/weavejs/compare/0.74.0...0.74.1 - [0.74.0]: https://github.com/InditexTech/weavejs/compare/0.73.1...0.74.0 - [0.73.1]: https://github.com/InditexTech/weavejs/compare/0.73.0...0.73.1 - [0.73.0]: https://github.com/InditexTech/weavejs/compare/0.72.1...0.73.0 - [0.72.1]: https://github.com/InditexTech/weavejs/compare/0.72.0...0.72.1 - [0.72.0]: https://github.com/InditexTech/weavejs/compare/0.71.0...0.72.0 - [0.71.0]: https://github.com/InditexTech/weavejs/compare/0.70.0...0.71.0 - [0.70.0]: https://github.com/InditexTech/weavejs/compare/0.69.2...0.70.0 - [0.69.2]: https://github.com/InditexTech/weavejs/compare/0.69.1...0.69.2 - [0.69.1]: https://github.com/InditexTech/weavejs/compare/0.69.0...0.69.1 - [0.69.0]: https://github.com/InditexTech/weavejs/compare/0.68.1...0.69.0 - [0.68.1]: https://github.com/InditexTech/weavejs/compare/0.68.0...0.68.1 - [0.68.0]: https://github.com/InditexTech/weavejs/compare/0.67.5...0.68.0 - [0.67.5]: https://github.com/InditexTech/weavejs/compare/0.67.4...0.67.5 - [0.67.4]: https://github.com/InditexTech/weavejs/compare/0.67.3...0.67.4 - [0.67.3]: https://github.com/InditexTech/weavejs/compare/0.67.2...0.67.3 - [0.67.2]: https://github.com/InditexTech/weavejs/compare/0.67.1...0.67.2 - [0.67.1]: https://github.com/InditexTech/weavejs/compare/0.67.0...0.67.1 - [0.67.0]: https://github.com/InditexTech/weavejs/compare/0.66.0...0.67.0 - [0.66.0]: https://github.com/InditexTech/weavejs/compare/0.64.0...0.66.0 - [0.64.0]: https://github.com/InditexTech/weavejs/compare/0.62.4...0.64.0 - [0.62.4]: https://github.com/InditexTech/weavejs/compare/0.62.3...0.62.4 - [0.62.3]: https://github.com/InditexTech/weavejs/compare/0.62.2...0.62.3 - [0.62.2]: https://github.com/InditexTech/weavejs/compare/0.62.1...0.62.2 - [0.62.1]: https://github.com/InditexTech/weavejs/compare/0.62.0...0.62.1 - [0.62.0]: https://github.com/InditexTech/weavejs/compare/0.61.0...0.62.0 - [0.61.0]: https://github.com/InditexTech/weavejs/compare/0.60.0...0.61.0 - [0.60.0]: https://github.com/InditexTech/weavejs/compare/0.59.0...0.60.0 - [0.59.0]: https://github.com/InditexTech/weavejs/compare/0.58.0...0.59.0 - [0.58.0]: https://github.com/InditexTech/weavejs/compare/0.57.1...0.58.0 - [0.57.1]: https://github.com/InditexTech/weavejs/compare/0.57.0...0.57.1 - [0.57.0]: https://github.com/InditexTech/weavejs/compare/0.56.2...0.57.0 - [0.56.2]: https://github.com/InditexTech/weavejs/compare/0.56.1...0.56.2 - [0.56.1]: https://github.com/InditexTech/weavejs/compare/0.56.0...0.56.1 - [0.56.0]: https://github.com/InditexTech/weavejs/compare/0.55.2...0.56.0 - [0.55.2]: https://github.com/InditexTech/weavejs/compare/0.55.1...0.55.2 - [0.55.1]: https://github.com/InditexTech/weavejs/compare/0.55.0...0.55.1 - [0.55.0]: https://github.com/InditexTech/weavejs/compare/0.54.1...0.55.0 - [0.54.1]: https://github.com/InditexTech/weavejs/compare/0.54.0...0.54.1 - [0.54.0]: https://github.com/InditexTech/weavejs/compare/0.53.0...0.54.0 - [0.53.0]: https://github.com/InditexTech/weavejs/compare/0.52.3...0.53.0 - [0.52.3]: https://github.com/InditexTech/weavejs/compare/0.52.2...0.52.3 - [0.52.2]: https://github.com/InditexTech/weavejs/compare/0.52.1...0.52.2 - [0.52.1]: https://github.com/InditexTech/weavejs/compare/0.52.0...0.52.1 - [0.52.0]: https://github.com/InditexTech/weavejs/compare/0.51.0...0.52.0 - [0.51.0]: https://github.com/InditexTech/weavejs/compare/0.50.0...0.51.0 - [0.50.0]: https://github.com/InditexTech/weavejs/compare/0.49.0...0.50.0 - [0.49.0]: https://github.com/InditexTech/weavejs/compare/0.48.0...0.49.0 - [0.48.0]: https://github.com/InditexTech/weavejs/compare/0.47.1...0.48.0 - [0.47.1]: https://github.com/InditexTech/weavejs/compare/0.47.0...0.47.1 - [0.47.0]: https://github.com/InditexTech/weavejs/compare/0.46.1...0.47.0 - [0.46.1]: https://github.com/InditexTech/weavejs/compare/0.46.0...0.46.1 - [0.46.0]: https://github.com/InditexTech/weavejs/compare/0.45.0...0.46.0 - [0.45.0]: https://github.com/InditexTech/weavejs/compare/0.44.0...0.45.0 - [0.44.0]: https://github.com/InditexTech/weavejs/compare/0.43.0...0.44.0 - [0.43.0]: https://github.com/InditexTech/weavejs/compare/0.42.2...0.43.0 - [0.42.2]: https://github.com/InditexTech/weavejs/compare/0.42.1...0.42.2 - [0.42.1]: https://github.com/InditexTech/weavejs/compare/0.42.0...0.42.1 - [0.42.0]: https://github.com/InditexTech/weavejs/compare/0.41.0...0.42.0 - [0.41.0]: https://github.com/InditexTech/weavejs/compare/0.40.2...0.41.0 - [0.40.2]: https://github.com/InditexTech/weavejs/compare/0.40.1...0.40.2 - [0.40.1]: https://github.com/InditexTech/weavejs/compare/0.40.0...0.40.1 - [0.40.0]: https://github.com/InditexTech/weavejs/compare/0.39.3...0.40.0 - [0.39.3]: https://github.com/InditexTech/weavejs/compare/0.39.2...0.39.3 - [0.39.2]: https://github.com/InditexTech/weavejs/compare/0.39.1...0.39.2 - [0.39.1]: https://github.com/InditexTech/weavejs/compare/0.39.0...0.39.1 - [0.39.0]: https://github.com/InditexTech/weavejs/compare/0.38.0...0.39.0 - [0.38.0]: https://github.com/InditexTech/weavejs/compare/0.37.0...0.38.0 - [0.37.0]: https://github.com/InditexTech/weavejs/compare/0.36.0...0.37.0 - [0.36.0]: https://github.com/InditexTech/weavejs/compare/0.35.0...0.36.0 - [0.35.0]: https://github.com/InditexTech/weavejs/compare/0.34.0...0.35.0 - [0.34.0]: https://github.com/InditexTech/weavejs/compare/0.33.0...0.34.0 - [0.33.0]: https://github.com/InditexTech/weavejs/compare/0.32.0...0.33.0 - [0.32.0]: https://github.com/InditexTech/weavejs/compare/0.31.1...0.32.0 - [0.31.1]: https://github.com/InditexTech/weavejs/compare/0.31.0...0.31.1 - [0.31.0]: https://github.com/InditexTech/weavejs/compare/0.30.1...0.31.0 - [0.30.1]: https://github.com/InditexTech/weavejs/compare/0.30.0...0.30.1 - [0.30.0]: https://github.com/InditexTech/weavejs/compare/0.29.1...0.30.0 - [0.29.1]: https://github.com/InditexTech/weavejs/compare/0.29.0...0.29.1 - [0.29.0]: https://github.com/InditexTech/weavejs/compare/0.28.0...0.29.0 - [0.28.0]: https://github.com/InditexTech/weavejs/compare/0.27.4...0.28.0 - [0.27.4]: https://github.com/InditexTech/weavejs/compare/0.27.3...0.27.4 - [0.27.3]: https://github.com/InditexTech/weavejs/compare/0.27.2...0.27.3 - [0.27.2]: https://github.com/InditexTech/weavejs/compare/0.27.1...0.27.2 - [0.27.1]: https://github.com/InditexTech/weavejs/compare/0.27.0...0.27.1 - [0.27.0]: https://github.com/InditexTech/weavejs/compare/0.26.2...0.27.0 - [0.26.2]: https://github.com/InditexTech/weavejs/compare/0.26.1...0.26.2 - [0.26.1]: https://github.com/InditexTech/weavejs/compare/0.26.0...0.26.1 - [0.26.0]: https://github.com/InditexTech/weavejs/compare/0.25.0...0.26.0 - [0.25.0]: https://github.com/InditexTech/weavejs/compare/0.24.1...0.25.0 - [0.24.1]: https://github.com/InditexTech/weavejs/compare/0.24.0...0.24.1 - [0.24.0]: https://github.com/InditexTech/weavejs/compare/0.23.1...0.24.0 - [0.23.1]: https://github.com/InditexTech/weavejs/compare/0.23.0...0.23.1 - [0.23.0]: https://github.com/InditexTech/weavejs/compare/0.22.1...0.23.0 - [0.22.1]: https://github.com/InditexTech/weavejs/compare/0.22.0...0.22.1 - [0.22.0]: https://github.com/InditexTech/weavejs/compare/0.21.2...0.22.0 - [0.21.2]: https://github.com/InditexTech/weavejs/compare/0.21.1...0.21.2 - [0.21.1]: https://github.com/InditexTech/weavejs/compare/0.21.0...0.21.1 - [0.21.0]: https://github.com/InditexTech/weavejs/compare/0.20.4...0.21.0 - [0.20.4]: https://github.com/InditexTech/weavejs/compare/0.20.3...0.20.4 - [0.20.3]: https://github.com/InditexTech/weavejs/compare/0.20.2...0.20.3 - [0.20.2]: https://github.com/InditexTech/weavejs/compare/0.20.1...0.20.2 - [0.20.1]: https://github.com/InditexTech/weavejs/compare/0.20.0...0.20.1 - [0.20.0]: https://github.com/InditexTech/weavejs/compare/0.19.0...0.20.0 - [0.19.0]: https://github.com/InditexTech/weavejs/compare/0.18.0...0.19.0 - [0.18.0]: https://github.com/InditexTech/weavejs/compare/0.17.0...0.18.0 - [0.17.0]: https://github.com/InditexTech/weavejs/compare/0.16.2...0.17.0 - [0.16.2]: https://github.com/InditexTech/weavejs/compare/0.16.1...0.16.2 - [0.16.1]: https://github.com/InditexTech/weavejs/compare/0.16.0...0.16.1 - [0.16.0]: https://github.com/InditexTech/weavejs/compare/0.15.0...0.16.0 - [0.15.0]: https://github.com/InditexTech/weavejs/compare/0.14.3...0.15.0 - [0.14.3]: https://github.com/InditexTech/weavejs/compare/0.14.2...0.14.3 - [0.14.2]: https://github.com/InditexTech/weavejs/compare/0.14.1...0.14.2 - [0.14.1]: https://github.com/InditexTech/weavejs/compare/0.14.0...0.14.1 - [0.14.0]: https://github.com/InditexTech/weavejs/compare/0.13.1...0.14.0 - [0.13.1]: https://github.com/InditexTech/weavejs/compare/0.13.0...0.13.1 - [0.13.0]: https://github.com/InditexTech/weavejs/compare/0.12.1...0.13.0 - [0.12.1]: https://github.com/InditexTech/weavejs/compare/0.12.0...0.12.1 - [0.12.0]: https://github.com/InditexTech/weavejs/compare/0.11.0...0.12.0 - [0.11.0]: https://github.com/InditexTech/weavejs/compare/0.10.3...0.11.0 - [0.10.3]: https://github.com/InditexTech/weavejs/compare/0.10.2...0.10.3 - [0.10.2]: https://github.com/InditexTech/weavejs/compare/0.10.1...0.10.2 - [0.10.1]: https://github.com/InditexTech/weavejs/compare/0.10.0...0.10.1 - [0.10.0]: https://github.com/InditexTech/weavejs/compare/0.9.3...0.10.0 - [0.9.3]: https://github.com/InditexTech/weavejs/compare/0.9.2...0.9.3 - [0.9.2]: https://github.com/InditexTech/weavejs/compare/0.9.1...0.9.2 - [0.9.1]: https://github.com/InditexTech/weavejs/compare/0.9.0...0.9.1 - [0.9.0]: https://github.com/InditexTech/weavejs/compare/0.8.0...0.9.0 - [0.8.0]: https://github.com/InditexTech/weavejs/compare/0.7.1...0.8.0 - [0.7.1]: https://github.com/InditexTech/weavejs/compare/0.7.0...0.7.1 - [0.7.0]: https://github.com/InditexTech/weavejs/compare/0.6.0...0.7.0 - [0.6.0]: https://github.com/InditexTech/weavejs/compare/0.5.0...0.6.0 - [0.5.0]: https://github.com/InditexTech/weavejs/compare/0.4.0...0.5.0 - [0.4.0]: https://github.com/InditexTech/weavejs/compare/0.3.3...0.4.0 - [0.3.3]: https://github.com/InditexTech/weavejs/compare/0.3.2...0.3.3 - [0.3.2]: https://github.com/InditexTech/weavejs/compare/0.3.1...0.3.2 - [0.3.1]: https://github.com/InditexTech/weavejs/compare/0.3.0...0.3.1 - [0.3.0]: https://github.com/InditexTech/weavejs/compare/0.2.1...0.3.0 - [0.2.1]: https://github.com/InditexTech/weavejs/compare/0.2.0...0.2.1 - [0.2.0]: https://github.com/InditexTech/weavejs/compare/0.1.1...0.2.0 - [0.1.1]: https://github.com/InditexTech/weavejs/compare/0.1.0...0.1.1 - [0.1.0]: https://github.com/InditexTech/weavejs/releases/tag/0.1.0 diff --git a/code/packages/renderer-konva-base/src/reconciler.ts b/code/packages/renderer-konva-base/src/reconciler.ts index 5179602a4..18646e21c 100644 --- a/code/packages/renderer-konva-base/src/reconciler.ts +++ b/code/packages/renderer-konva-base/src/reconciler.ts @@ -114,11 +114,7 @@ export const SIMPLE_RECONCILER = { child.setZIndex(index); } }, - removeChild( - instance: Weave, - parent: WeaveElementInstance | undefined, - child: WeaveElementInstance - ) { + removeChild(instance: Weave, child: WeaveElementInstance) { const type = child.getAttrs().nodeType; const handler = instance.getNodeHandler(type); diff --git a/code/packages/renderer-konva-base/src/renderer.ts b/code/packages/renderer-konva-base/src/renderer.ts index b290239dc..c644dd599 100644 --- a/code/packages/renderer-konva-base/src/renderer.ts +++ b/code/packages/renderer-konva-base/src/renderer.ts @@ -299,23 +299,23 @@ export class WeaveKonvaBaseRenderer extends WeaveRenderer { const stage = this.instance.getStage(); - const parentInstance = stage.findOne(`#${instruction.parentKey}`) as - | Stage - | Layer - | Group; - - const childInstance = stage.findOne( + const childInstances: WeaveElementInstance[] = stage.find( `#${instruction.key}` - ) as WeaveElementInstance; + ); - if (!childInstance) { - console.warn( - `Trying to remove non existing node with key ${instruction.key}` - ); - return; - } + for (const childInstance of childInstances) { + let parent = childInstance.getParent(); + if (parent && parent.getAttrs().nodeId) { + parent = stage.findOne(`#${parent.getAttrs().nodeId}`) as + | Stage + | Layer + | Group; + } - this.reconciler.removeChild(this.instance, parentInstance, childInstance); + if (parent?.id() === instruction.parentKey) { + this.reconciler.removeChild(this.instance, childInstance); + } + } } private updateProps(instruction: RendererInstruction) { @@ -330,9 +330,6 @@ export class WeaveKonvaBaseRenderer extends WeaveRenderer { const node = stage.findOne(`#${instruction.key}`) as WeaveElementInstance; if (!node) { - console.warn( - `Trying to update non existing node with key ${instruction.key}` - ); return; } diff --git a/code/packages/sdk/src/actions/image-tool/image-tool.ts b/code/packages/sdk/src/actions/image-tool/image-tool.ts index f37f49886..a4cfaed7c 100644 --- a/code/packages/sdk/src/actions/image-tool/image-tool.ts +++ b/code/packages/sdk/src/actions/image-tool/image-tool.ts @@ -29,10 +29,7 @@ import { WeaveNodesSelectionPlugin } from '@/plugins/nodes-selection/nodes-selec import Konva from 'konva'; import type { WeaveImageNode } from '@/nodes/image/image'; import { SELECTION_TOOL_ACTION_NAME } from '../selection-tool/constants'; -import { - getPositionRelativeToContainerOnPosition, - mergeExceptArrays, -} from '@/utils/utils'; +import { mergeExceptArrays } from '@/utils/utils'; import type { WeaveElementAttributes, WeaveElementInstance, @@ -109,8 +106,9 @@ export class WeaveImageToolAction extends WeaveAction { if (dragProperties && dragId === WEAVE_IMAGE_TOOL_ACTION_NAME) { this.instance.getStage().setPointersPositions(e); - const position: Konva.Vector2d | null | undefined = - getPositionRelativeToContainerOnPosition(this.instance); + const position: Konva.Vector2d | null | undefined = this.instance + .getStage() + .getRelativePointerPosition(); if (!position) { return; diff --git a/code/packages/sdk/src/actions/images-tool/images-tool.ts b/code/packages/sdk/src/actions/images-tool/images-tool.ts index 651d9d1ee..7ef4ed14e 100644 --- a/code/packages/sdk/src/actions/images-tool/images-tool.ts +++ b/code/packages/sdk/src/actions/images-tool/images-tool.ts @@ -29,10 +29,7 @@ import { WEAVE_IMAGES_TOOL_UPLOAD_TYPE, } from './constants'; import { WeaveAction } from '../action'; -import { - getPositionRelativeToContainerOnPosition, - mergeExceptArrays, -} from '@/utils/utils'; +import { mergeExceptArrays } from '@/utils/utils'; import type { WeaveImageToolAction } from '../image-tool/image-tool'; import { WEAVE_IMAGE_TOOL_ACTION_NAME, @@ -120,8 +117,9 @@ export class WeaveImagesToolAction extends WeaveAction { if (dragProperties && dragId === WEAVE_IMAGES_TOOL_ACTION_NAME) { this.instance.getStage().setPointersPositions(e); - const position: Konva.Vector2d | null | undefined = - getPositionRelativeToContainerOnPosition(this.instance); + const position: Konva.Vector2d | null | undefined = this.instance + .getStage() + .getRelativePointerPosition(); if (!position) { return; diff --git a/code/packages/sdk/src/actions/video-tool/video-tool.ts b/code/packages/sdk/src/actions/video-tool/video-tool.ts index 5a673624a..30742e06b 100644 --- a/code/packages/sdk/src/actions/video-tool/video-tool.ts +++ b/code/packages/sdk/src/actions/video-tool/video-tool.ts @@ -18,7 +18,6 @@ import { WeaveNodesSelectionPlugin } from '@/plugins/nodes-selection/nodes-selec import Konva from 'konva'; import { SELECTION_TOOL_ACTION_NAME } from '../selection-tool/constants'; import type { WeaveVideoNode } from '@/nodes/video/video'; -import { getPositionRelativeToContainerOnPosition } from '@/utils/utils'; export class WeaveVideoToolAction extends WeaveAction { protected initialized: boolean = false; @@ -82,8 +81,9 @@ export class WeaveVideoToolAction extends WeaveAction { if (dragProperties && dragId === VIDEO_TOOL_ACTION_NAME) { this.instance.getStage().setPointersPositions(e); - const position: Konva.Vector2d | null | undefined = - getPositionRelativeToContainerOnPosition(this.instance); + const position: Konva.Vector2d | null | undefined = this.instance + .getStage() + .getRelativePointerPosition(); this.instance.triggerAction(VIDEO_TOOL_ACTION_NAME, { videoId: dragProperties.videoId, diff --git a/code/packages/sdk/src/managers/targeting.ts b/code/packages/sdk/src/managers/targeting.ts index 5bb4ebcd4..b6d09129d 100644 --- a/code/packages/sdk/src/managers/targeting.ts +++ b/code/packages/sdk/src/managers/targeting.ts @@ -10,7 +10,7 @@ import type { WeaveMousePointInfoSimple, } from '@inditextech/weave-types'; import type { WeaveNodesSelectionPlugin } from '@/plugins/nodes-selection/nodes-selection'; -import { getBoundingBox } from '@/utils/utils'; +import { containerOverCursor, getBoundingBox } from '@/utils/utils'; export class WeaveTargetingManager { private instance: Weave; @@ -181,21 +181,24 @@ export class WeaveTargetingManager { getMousePointer(point?: Konva.Vector2d): WeaveMousePointInfo { this.logger.debug({ point }, 'getMousePointer'); - const stage = this.instance.getStage(); const mainLayer = this.instance.getMainLayer(); let relativeMousePointer = typeof point !== 'undefined' ? point : mainLayer?.getRelativePointerPosition() ?? { x: 0, y: 0 }; - let measureContainer: Konva.Layer | Konva.Group | undefined = mainLayer; - let container: Konva.Layer | Konva.Node | undefined = mainLayer; const utilityLayer = this.instance.getUtilityLayer(); if (utilityLayer) { utilityLayer.visible(false); } + const containerAlt = containerOverCursor( + this.instance, + [], + relativeMousePointer + ); + const nodesSelection = this.instance.getPlugin('nodesSelection'); @@ -203,42 +206,8 @@ export class WeaveTargetingManager { nodesSelection.getTransformer().visible(false); } - const dummyRect = new Konva.Rect({ - width: 10, - height: 10, - x: relativeMousePointer.x, - y: relativeMousePointer.y, - }); - mainLayer?.add(dummyRect); - - const intersectedNode = this.nodeIntersectsContainerElement(dummyRect); - if (intersectedNode) { - const containerOfNode = stage.findOne( - `#${intersectedNode.getAttrs().containerId}` - ) as Konva.Group | undefined; - if (containerOfNode) { - container = intersectedNode; - measureContainer = containerOfNode; - } - } - - if ( - typeof point === 'undefined' && - container?.getAttrs().nodeType !== 'layer' - ) { - relativeMousePointer = - measureContainer?.getRelativePointerPosition() ?? relativeMousePointer; - } - - if ( - typeof point === 'undefined' && - container?.getAttrs().nodeType === 'layer' - ) { - relativeMousePointer = measureContainer?.getRelativePointerPosition() ?? { - x: 0, - y: 0, - }; - } + relativeMousePointer = + containerAlt?.getRelativePointerPosition() ?? relativeMousePointer; if (utilityLayer) { utilityLayer.visible(true); @@ -248,9 +217,11 @@ export class WeaveTargetingManager { nodesSelection.getTransformer().visible(true); } - dummyRect.destroy(); - - return { mousePoint: relativeMousePointer, container, measureContainer }; + return { + mousePoint: relativeMousePointer, + container: containerAlt, + measureContainer: containerAlt, + }; } getMousePointerRelativeToContainer( diff --git a/code/packages/sdk/src/nodes/connector/connector.ts b/code/packages/sdk/src/nodes/connector/connector.ts index f4cd235ac..daf432a32 100644 --- a/code/packages/sdk/src/nodes/connector/connector.ts +++ b/code/packages/sdk/src/nodes/connector/connector.ts @@ -1222,7 +1222,6 @@ export class WeaveConnectorNode extends WeaveNode { delete cleanedAttrs.startInfoLoaded; delete cleanedAttrs.endInfoLoaded; delete cleanedAttrs.overridesMouseControl; - delete cleanedAttrs.onMoveContainer; delete cleanedAttrs.dragBoundFunc; return { diff --git a/code/packages/sdk/src/nodes/extensions.d.ts b/code/packages/sdk/src/nodes/extensions.d.ts index aa97a9fb0..b0bc49a79 100644 --- a/code/packages/sdk/src/nodes/extensions.d.ts +++ b/code/packages/sdk/src/nodes/extensions.d.ts @@ -48,7 +48,6 @@ declare module 'konva/lib/Node' { updatePosition(position: Vector2d): void; dblClick(): void; isSelectable(): boolean; - movedToContainer(container: Konva.Layer | Konva.Group): void; handleMouseover(e: KonvaEventObject): void; handleMouseout(e: KonvaEventObject): void; handleSelectNode(): void; diff --git a/code/packages/sdk/src/nodes/frame/frame.ts b/code/packages/sdk/src/nodes/frame/frame.ts index 3beb17c67..3f0a50bb5 100644 --- a/code/packages/sdk/src/nodes/frame/frame.ts +++ b/code/packages/sdk/src/nodes/frame/frame.ts @@ -411,7 +411,6 @@ export class WeaveFrameNode extends WeaveNode { delete cleanedAttrs.draggable; delete cleanedAttrs.onTargetEnter; delete cleanedAttrs.overridesMouseControl; - delete cleanedAttrs.onMoveContainer; delete cleanedAttrs.dragBoundFunc; return { diff --git a/code/packages/sdk/src/nodes/group/group.ts b/code/packages/sdk/src/nodes/group/group.ts index 388b5d4b8..76b815d56 100644 --- a/code/packages/sdk/src/nodes/group/group.ts +++ b/code/packages/sdk/src/nodes/group/group.ts @@ -129,7 +129,6 @@ export class WeaveGroupNode extends WeaveNode { delete cleanedAttrs.mutexUserId; delete cleanedAttrs.draggable; delete cleanedAttrs.overridesMouseControl; - delete cleanedAttrs.onMoveContainer; delete cleanedAttrs.dragBoundFunc; return { diff --git a/code/packages/sdk/src/nodes/image/constants.ts b/code/packages/sdk/src/nodes/image/constants.ts index 2e18c80eb..fb3000a24 100644 --- a/code/packages/sdk/src/nodes/image/constants.ts +++ b/code/packages/sdk/src/nodes/image/constants.ts @@ -26,6 +26,9 @@ export const WEAVE_IMAGE_CROP_ANCHOR_POSITION = { } as const; export const WEAVE_IMAGE_DEFAULT_CONFIG: WeaveImageProperties = { + cleanup: { + intervalMs: 60 * 1000, // 1 minute + }, performance: { cache: { enabled: false, diff --git a/code/packages/sdk/src/nodes/image/image.ts b/code/packages/sdk/src/nodes/image/image.ts index a9bd253b0..540d38554 100644 --- a/code/packages/sdk/src/nodes/image/image.ts +++ b/code/packages/sdk/src/nodes/image/image.ts @@ -43,6 +43,7 @@ export class WeaveImageNode extends WeaveNode { protected tapStart!: { x: number; y: number; time: number } | null; protected imageCrop!: WeaveImageCrop | null; protected nodeType: string = WEAVE_IMAGE_NODE_TYPE; + protected notUsedImagesCleanup!: NodeJS.Timeout | null; private readonly cursorsFallback: WeaveImageCursors = { loading: 'wait', }; @@ -69,6 +70,34 @@ export class WeaveImageNode extends WeaveNode { this.imageFallback = {}; } + private setupNotUsedImagesCleanup() { + const cleanupHandler = () => { + this.notUsedImagesCleanup = null; + const stage = this.instance.getStage(); + + const nodesIds = Object.keys(this.imageState); + + for (const nodeId of nodesIds) { + const node = stage.findOne(`#${nodeId}`) as Konva.Node | undefined; + + if (!node) { + delete this.imageSource[nodeId]; + delete this.imageState[nodeId]; + delete this.imageTryoutAttempts[nodeId]; + delete this.imageFallback[nodeId]; + } + } + + this.setupNotUsedImagesCleanup(); + }; + + const bindedCleanupHandler = cleanupHandler.bind(this); + + if (!this.notUsedImagesCleanup) { + setTimeout(bindedCleanupHandler, this.config.cleanup.intervalMs); + } + } + preloadCursors() { return new Promise((resolve) => { (async () => { @@ -237,6 +266,8 @@ export class WeaveImageNode extends WeaveNode { onRender(props: WeaveElementAttributes): WeaveElementInstance { // this.initGlobalEvents(); + this.setupNotUsedImagesCleanup(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const imageProperties: any = props.imageProperties; const imageProps = props as ImageProps; @@ -280,15 +311,6 @@ export class WeaveImageNode extends WeaveNode { return 'pointer'; }; - image.movedToContainer = () => { - const stage = this.instance.getStage(); - const image = stage.findOne(`#${id}`) as Konva.Group | undefined; - - if (!image) { - return; - } - }; - if (this.config.cropMode.enabled) { image.triggerCrop = () => { this.triggerCrop(image, { @@ -1403,9 +1425,6 @@ export class WeaveImageNode extends WeaveNode { onDestroy(nodeInstance: WeaveElementInstance) { const nodeId = nodeInstance.getAttrs().id ?? ''; - const isMoveContainer = nodeInstance.getAttr('onMoveContainer'); - nodeInstance.setAttr('onMoveContainer', undefined); - const utilityLayer = this.instance.getUtilityLayer(); const nodes = utilityLayer?.find('.cropMode') ?? []; nodes.forEach((n) => { @@ -1417,13 +1436,6 @@ export class WeaveImageNode extends WeaveNode { delete this.imageTryoutIds[nodeId]; } - if (!isMoveContainer) { - delete this.imageSource[nodeId]; - delete this.imageState[nodeId]; - delete this.imageTryoutAttempts[nodeId]; - delete this.imageFallback[nodeId]; - } - nodeInstance.destroy(); } } diff --git a/code/packages/sdk/src/nodes/image/types.ts b/code/packages/sdk/src/nodes/image/types.ts index 8321efc9e..1669a804e 100644 --- a/code/packages/sdk/src/nodes/image/types.ts +++ b/code/packages/sdk/src/nodes/image/types.ts @@ -47,6 +47,9 @@ export type WeaveImageCursors = { }; export type WeaveImageProperties = { + cleanup: { + intervalMs: number; + }; performance: { cache: WeaveImageCache; }; diff --git a/code/packages/sdk/src/nodes/layer/layer.ts b/code/packages/sdk/src/nodes/layer/layer.ts index 913e3bfec..b7bbb0e29 100644 --- a/code/packages/sdk/src/nodes/layer/layer.ts +++ b/code/packages/sdk/src/nodes/layer/layer.ts @@ -58,7 +58,6 @@ export class WeaveLayerNode extends WeaveNode { delete cleanedAttrs.mutexUserId; delete cleanedAttrs.draggable; delete cleanedAttrs.overridesMouseControl; - delete cleanedAttrs.onMoveContainer; delete cleanedAttrs.dragBoundFunc; return { diff --git a/code/packages/sdk/src/nodes/node.ts b/code/packages/sdk/src/nodes/node.ts index e0be6b4c8..0970b1f67 100644 --- a/code/packages/sdk/src/nodes/node.ts +++ b/code/packages/sdk/src/nodes/node.ts @@ -56,7 +56,6 @@ export const augmentKonvaNodeClass = ( Konva.Node.prototype.getRealClientRect = function (config) { return this.getClientRect(config); }; - Konva.Node.prototype.movedToContainer = function () {}; Konva.Node.prototype.updatePosition = function () {}; Konva.Node.prototype.triggerCrop = function () {}; Konva.Node.prototype.closeCrop = function () {}; @@ -130,7 +129,6 @@ export abstract class WeaveNode implements WeaveNodeBase { 'bottom-right', ]; }; - node.movedToContainer = function () {}; node.updatePosition = function () {}; node.resetCrop = function () {}; node.handleMouseover = function () {}; @@ -414,7 +412,13 @@ export abstract class WeaveNode implements WeaveNodeBase { nodesEdgeSnappingPlugin.evaluateGuidelines(e); } - this.getUsersPresencePlugin()?.setPresence(node.id(), { + let parentId: string = node.getParent()?.id() ?? ''; + const parent = node.getParent(); + if (parent?.getAttrs().nodeId) { + parentId = parent.getAttrs().nodeId; + } + + this.getUsersPresencePlugin()?.setPresence(node.id(), parentId, { x: node.x(), y: node.y(), width: node.width(), @@ -678,10 +682,20 @@ export abstract class WeaveNode implements WeaveNodeBase { ) { clearContainerTargets(this.instance); - this.getUsersPresencePlugin()?.setPresence(realNodeTarget.id(), { - x: realNodeTarget.x(), - y: realNodeTarget.y(), - }); + let parentId: string = realNodeTarget.getParent()?.id() ?? ''; + const parent = realNodeTarget.getParent(); + if (parent?.getAttrs().nodeId) { + parentId = parent.getAttrs().nodeId; + } + + this.getUsersPresencePlugin()?.setPresence( + realNodeTarget.id(), + parentId, + { + x: realNodeTarget.x(), + y: realNodeTarget.y(), + } + ); const layerToMove = containerOverCursor(this.instance, [ realNodeTarget, @@ -1108,7 +1122,6 @@ export abstract class WeaveNode implements WeaveNodeBase { delete cleanedAttrs.mutexUserId; delete cleanedAttrs.draggable; delete cleanedAttrs.overridesMouseControl; - delete cleanedAttrs.onMoveContainer; delete cleanedAttrs.dragBoundFunc; return { diff --git a/code/packages/sdk/src/nodes/stroke/stroke.ts b/code/packages/sdk/src/nodes/stroke/stroke.ts index b7173cfec..f44792deb 100644 --- a/code/packages/sdk/src/nodes/stroke/stroke.ts +++ b/code/packages/sdk/src/nodes/stroke/stroke.ts @@ -295,7 +295,6 @@ export class WeaveStrokeNode extends WeaveNode { delete cleanedAttrs.sceneFunc; delete cleanedAttrs.hitFunc; delete cleanedAttrs.overridesMouseControl; - delete cleanedAttrs.onMoveContainer; delete cleanedAttrs.dragBoundFunc; return { diff --git a/code/packages/sdk/src/nodes/text/text.ts b/code/packages/sdk/src/nodes/text/text.ts index eea451d02..703ab55a4 100644 --- a/code/packages/sdk/src/nodes/text/text.ts +++ b/code/packages/sdk/src/nodes/text/text.ts @@ -467,7 +467,6 @@ export class WeaveTextNode extends WeaveNode { delete cleanedAttrs.measureMultilineText; delete cleanedAttrs.overridesMouseControl; delete cleanedAttrs.shouldUpdateOnTransform; - delete cleanedAttrs.onMoveContainer; delete cleanedAttrs.dragBoundFunc; return { diff --git a/code/packages/sdk/src/nodes/video/video.ts b/code/packages/sdk/src/nodes/video/video.ts index 574965f63..ef86bd2a4 100644 --- a/code/packages/sdk/src/nodes/video/video.ts +++ b/code/packages/sdk/src/nodes/video/video.ts @@ -80,6 +80,10 @@ export class WeaveVideoNode extends WeaveNode { video ) ?? videoProps.videoPlaceholderURL; + if (!this.videoPlaceholder) { + this.initialize(); + } + this.videoPlaceholder[id] = Konva.Util.createImageElement(); this.videoPlaceholder[id].crossOrigin = this.config.crossOrigin; this.videoPlaceholder[id].src = realVideoPlaceholderURL; diff --git a/code/packages/sdk/src/plugins/nodes-selection/nodes-selection.ts b/code/packages/sdk/src/plugins/nodes-selection/nodes-selection.ts index 07db52056..ab2590333 100644 --- a/code/packages/sdk/src/plugins/nodes-selection/nodes-selection.ts +++ b/code/packages/sdk/src/plugins/nodes-selection/nodes-selection.ts @@ -369,8 +369,15 @@ export class WeaveNodesSelectionPlugin extends WeavePlugin { if (this.getUsersPresencePlugin()) { for (const node of tr.nodes()) { + let parentId: string = node.getParent()?.id() ?? ''; + const parent = node.getParent(); + if (parent?.getAttrs().nodeId) { + parentId = parent.getAttrs().nodeId; + } + this.getUsersPresencePlugin()?.setPresence( node.id(), + parentId, { x: node.x(), y: node.y(), @@ -523,8 +530,15 @@ export class WeaveNodesSelectionPlugin extends WeavePlugin { if (this.getUsersPresencePlugin() && this.dragInProcess) { for (const node of selectedNodes) { + let parentId: string = node.getParent()?.id() ?? ''; + const parent = node.getParent(); + if (parent?.getAttrs().nodeId) { + parentId = parent.getAttrs().nodeId; + } + this.getUsersPresencePlugin()?.setPresence( node.id(), + parentId, { x: node.x(), y: node.y(), diff --git a/code/packages/sdk/src/plugins/users-presence/types.ts b/code/packages/sdk/src/plugins/users-presence/types.ts index e8499eae5..b22b0d3bb 100644 --- a/code/packages/sdk/src/plugins/users-presence/types.ts +++ b/code/packages/sdk/src/plugins/users-presence/types.ts @@ -21,6 +21,7 @@ export type WeaveUserPresenceInformation = Record< export type WeaveUserPresence = { userId: string; + parentId: string; nodeId: string; attrs: T; }; diff --git a/code/packages/sdk/src/plugins/users-presence/users-presence.ts b/code/packages/sdk/src/plugins/users-presence/users-presence.ts index 28f375167..bdecc262b 100644 --- a/code/packages/sdk/src/plugins/users-presence/users-presence.ts +++ b/code/packages/sdk/src/plugins/users-presence/users-presence.ts @@ -75,7 +75,17 @@ export class WeaveUsersPresencePlugin extends WeavePlugin { const nodeInstance = stage.findOne(`#${presenceInfo.nodeId}`); - if (nodeInstance) { + if (!nodeInstance) { + continue; + } + + let parentId: string = nodeInstance.getParent()?.id() ?? ''; + const parent = nodeInstance.getParent(); + if (parent?.getAttrs().nodeId) { + parentId = parent.getAttrs().nodeId; + } + + if (nodeInstance && presenceInfo.parentId === parentId) { const newProps = { ...nodeInstance.getAttrs(), ...(presenceInfo.attrs as Record), @@ -93,11 +103,17 @@ export class WeaveUsersPresencePlugin extends WeavePlugin { store.setAwarenessInfo(WEAVE_USER_PRESENCE_KEY, this.userPresence); } - setPresence(nodeId: string, attrs: T, forceUpdate = true) { + setPresence( + nodeId: string, + parentId: string, + attrs: T, + forceUpdate = true + ) { const userInfo = this.config.getUser(); this.userPresence[nodeId] = { userId: userInfo.id, + parentId, nodeId, attrs, }; diff --git a/code/packages/sdk/src/utils/utils.ts b/code/packages/sdk/src/utils/utils.ts index 6d5fcf6e3..87a4617b1 100644 --- a/code/packages/sdk/src/utils/utils.ts +++ b/code/packages/sdk/src/utils/utils.ts @@ -195,10 +195,11 @@ export function moveNodeToContainerNT( node.rotation(nodeRotation); node.x(node.x() - (layerToMoveAttrs.containerOffsetX ?? 0)); node.y(node.y() - (layerToMoveAttrs.containerOffsetY ?? 0)); - node.movedToContainer(layerToMove); + node.destroy(); + const newNode: Konva.Node = node.clone(); instance.emitEvent('onNodeMovedToContainer', { - node: node.clone(), + node: newNode, container: layerToMove, originalNode, originalContainer, @@ -209,10 +210,14 @@ export function moveNodeToContainerNT( ); if (nodeHandler) { - node.setAttrs({ onMoveContainer: true }); - const actualNode = nodeHandler.serialize(node as WeaveElementInstance); - instance.removeNodeNT(actualNode, { emitUserChangeEvent: false }); - instance.addNodeNT(actualNode, layerToMoveAttrs.id, { + const actualNodeState = nodeHandler.serialize( + node as WeaveElementInstance + ); + const newNodeState = nodeHandler.serialize( + newNode as WeaveElementInstance + ); + instance.removeNodeNT(actualNodeState, { emitUserChangeEvent: false }); + instance.addNodeNT(newNodeState, layerToMoveAttrs.id, { // emitUserChangeEvent: true, emitUserChangeEvent: false, overrideUserChangeType: WEAVE_NODE_CHANGE_TYPE.UPDATE, @@ -633,40 +638,6 @@ export function isIOS() { export const isServer = () => typeof window === 'undefined'; -export const getPositionRelativeToContainerOnPosition = ( - instance: Weave -): Konva.Vector2d | null | undefined => { - let position: Konva.Vector2d | null | undefined = instance - .getStage() - .getRelativePointerPosition(); - - if (!position) { - return position; - } - - const container = containerOverCursor(instance, [], position); - - if (container) { - if (container.getAttrs().containerId) { - const containerNode = container.findOne( - `#${container.getAttrs().containerId}` - ) as Konva.Group; - - if (containerNode) { - position = containerNode?.getRelativePointerPosition(); - } - } else { - position = container?.getRelativePointerPosition(); - } - } - - if (!position) { - return position; - } - - return position; -}; - export const canComposite = (node: Konva.Node) => { const parent = node.getParent(); diff --git a/code/packages/sdk/src/weave.ts b/code/packages/sdk/src/weave.ts index 877e2d7e9..1e3e3eaed 100644 --- a/code/packages/sdk/src/weave.ts +++ b/code/packages/sdk/src/weave.ts @@ -232,10 +232,7 @@ export class Weave { if (!this.isServerSide()) { this.eventsController = new AbortController(); - // Setup the instance on the weave global variable - if (!window.weave) { - window.weave = this; - } + window.weave = this; } this.emitEvent('onRoomLoaded', false); diff --git a/docs/content/docs/main/changelog/3.x/3.8.1.mdx b/docs/content/docs/main/changelog/3.x/3.8.1.mdx new file mode 100644 index 000000000..d8f329aea --- /dev/null +++ b/docs/content/docs/main/changelog/3.x/3.8.1.mdx @@ -0,0 +1,12 @@ +--- +title: v3.8.1 +description: Important bugfixes related to base renderer / reconciler +--- + +## Metadata + +- **Release date**: 2026-05-11 + +### Fixed + +- [#1044](https://github.com/InditexTech/weavejs/issues/1044) Nodes disappear when moving between frames diff --git a/docs/content/docs/main/changelog/3.x/meta.json b/docs/content/docs/main/changelog/3.x/meta.json index 8d2a8162a..13a209421 100644 --- a/docs/content/docs/main/changelog/3.x/meta.json +++ b/docs/content/docs/main/changelog/3.x/meta.json @@ -2,6 +2,7 @@ "title": "3.x versions", "description": "Detailed changelog for Weave.js 3.x versions", "pages": [ + "3.8.1", "3.8.0", "3.7.2", "3.7.1", diff --git a/docs/content/docs/main/changelog/index.mdx b/docs/content/docs/main/changelog/index.mdx index d509d82dd..b63dd1811 100644 --- a/docs/content/docs/main/changelog/index.mdx +++ b/docs/content/docs/main/changelog/index.mdx @@ -5,6 +5,7 @@ description: Check out the latest changes to Weave.js. ## 3.x versions +- [**3.8.1**](/docs/main/changelog/3.x/3.8.1) - [**3.8.0**](/docs/main/changelog/3.x/3.8.0) - [**3.7.2**](/docs/main/changelog/3.x/3.7.2) - [**3.7.1**](/docs/main/changelog/3.x/3.7.1) From 75c623166b6cbb5779a66d1ed1cf49d5f956cd29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Mon, 11 May 2026 09:06:56 +0200 Subject: [PATCH 03/12] chore: fix sonar qube issues --- code/packages/renderer-konva-base/src/renderer.ts | 12 ++++-------- code/packages/sdk/src/nodes/image/image.ts | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/code/packages/renderer-konva-base/src/renderer.ts b/code/packages/renderer-konva-base/src/renderer.ts index c644dd599..26d3c2521 100644 --- a/code/packages/renderer-konva-base/src/renderer.ts +++ b/code/packages/renderer-konva-base/src/renderer.ts @@ -11,9 +11,6 @@ import { } from '@inditextech/weave-types'; import Konva from 'konva'; import { isEqual } from 'lodash'; -import type { Stage } from 'konva/lib/Stage'; -import type { Layer } from 'konva/lib/Layer'; -import type { Group } from 'konva/lib/Group'; import type { RendererInstruction } from './types'; import { SIMPLE_RECONCILER } from './reconciler'; import { WeaveRenderer } from '@inditextech/weave-sdk'; @@ -305,11 +302,10 @@ export class WeaveKonvaBaseRenderer extends WeaveRenderer { for (const childInstance of childInstances) { let parent = childInstance.getParent(); - if (parent && parent.getAttrs().nodeId) { - parent = stage.findOne(`#${parent.getAttrs().nodeId}`) as - | Stage - | Layer - | Group; + if (parent?.getAttrs().nodeId) { + parent = stage.findOne( + `#${parent.getAttrs().nodeId}` + ) as Konva.Container; } if (parent?.id() === instruction.parentKey) { diff --git a/code/packages/sdk/src/nodes/image/image.ts b/code/packages/sdk/src/nodes/image/image.ts index 540d38554..d064019bb 100644 --- a/code/packages/sdk/src/nodes/image/image.ts +++ b/code/packages/sdk/src/nodes/image/image.ts @@ -78,7 +78,7 @@ export class WeaveImageNode extends WeaveNode { const nodesIds = Object.keys(this.imageState); for (const nodeId of nodesIds) { - const node = stage.findOne(`#${nodeId}`) as Konva.Node | undefined; + const node = stage.findOne(`#${nodeId}`); if (!node) { delete this.imageSource[nodeId]; From 7e9e04b72791a61561741845405cd2ada21750fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Mon, 11 May 2026 10:27:03 +0200 Subject: [PATCH 04/12] chore: fix mainLayer container on detection instead of undefined --- code/packages/sdk/src/managers/targeting.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/packages/sdk/src/managers/targeting.ts b/code/packages/sdk/src/managers/targeting.ts index b6d09129d..ed13742b9 100644 --- a/code/packages/sdk/src/managers/targeting.ts +++ b/code/packages/sdk/src/managers/targeting.ts @@ -193,12 +193,16 @@ export class WeaveTargetingManager { utilityLayer.visible(false); } - const containerAlt = containerOverCursor( + let containerAlt = containerOverCursor( this.instance, [], relativeMousePointer ); + if (!containerAlt) { + containerAlt = this.instance.getMainLayer(); + } + const nodesSelection = this.instance.getPlugin('nodesSelection'); From 9d980f609c342699e130d942396ea8f4b9ded02e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Mon, 11 May 2026 10:39:55 +0200 Subject: [PATCH 05/12] chore: restore real opacity on drag --- code/packages/sdk/src/nodes/node.ts | 11 +++-------- .../src/plugins/nodes-selection/nodes-selection.ts | 9 +-------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/code/packages/sdk/src/nodes/node.ts b/code/packages/sdk/src/nodes/node.ts index 38ff1edfd..dfd8662a9 100644 --- a/code/packages/sdk/src/nodes/node.ts +++ b/code/packages/sdk/src/nodes/node.ts @@ -527,11 +527,6 @@ export abstract class WeaveNode implements WeaveNodeBase { this.getNodesSelectionFeedbackPlugin()?.hideSelectionHalo(nodeTarget); - this.getSelectionPlugin()?.saveDragSelectedNodes(); - if (this.getSelectionPlugin()?.getDragSelectedNodes().length === 1) { - this.getSelectionPlugin()?.setNodesOpacityOnDrag(); - } - const canMove = nodeTarget?.canDrag() ?? false; if (!canMove) { @@ -758,9 +753,9 @@ export abstract class WeaveNode implements WeaveNodeBase { lockedAxis = null; isShiftPressed = false; - if (this.getSelectionPlugin()?.getDragSelectedNodes().length === 1) { - this.getSelectionPlugin()?.restoreNodesOpacityOnDrag(); - } + // if (this.getSelectionPlugin()?.getDragSelectedNodes().length === 1) { + this.getSelectionPlugin()?.restoreNodesOpacityOnDrag(); + // } if (this.getSelectionPlugin()?.getSelectedNodes().length === 1) { this.instance.releaseMutexLock(); diff --git a/code/packages/sdk/src/plugins/nodes-selection/nodes-selection.ts b/code/packages/sdk/src/plugins/nodes-selection/nodes-selection.ts index ab2590333..c542cb153 100644 --- a/code/packages/sdk/src/plugins/nodes-selection/nodes-selection.ts +++ b/code/packages/sdk/src/plugins/nodes-selection/nodes-selection.ts @@ -447,10 +447,7 @@ export class WeaveNodesSelectionPlugin extends WeavePlugin { const stage = this.instance.getStage(); this.saveDragSelectedNodes(); - - if (this.getDragSelectedNodes().length > 1) { - this.setNodesOpacityOnDrag(); - } + this.setNodesOpacityOnDrag(); selectedNodes = tr.nodes(); @@ -573,10 +570,6 @@ export class WeaveNodesSelectionPlugin extends WeavePlugin { this.instance.getSelectionLayer()?.hitGraphEnabled(true); this.instance.getMainLayer()?.hitGraphEnabled(true); - if (this.getDragSelectedNodes().length > 1) { - this.restoreNodesOpacityOnDrag(); - } - if (!this.didMove) { return; } From 060c98e3356f47fdc39ba4e001b4760a00871330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Mon, 11 May 2026 11:33:58 +0200 Subject: [PATCH 06/12] chore: fix docs issues --- docs/content/docs/main/changelog/3.x/3.8.1.mdx | 8 -------- 1 file changed, 8 deletions(-) diff --git a/docs/content/docs/main/changelog/3.x/3.8.1.mdx b/docs/content/docs/main/changelog/3.x/3.8.1.mdx index f5d1907bb..03d9d69e1 100644 --- a/docs/content/docs/main/changelog/3.x/3.8.1.mdx +++ b/docs/content/docs/main/changelog/3.x/3.8.1.mdx @@ -1,10 +1,6 @@ --- title: v3.8.1 -<<<<<<< bugfix/GH-1044-nodes-dissapear-when-moving-b -description: Important bugfixes related to base renderer / reconciler and minor fixes for pan stage when dragging elements near border and to avoid pasting a frame onto a frame -======= description: Fix to pan stage when dragging elements near border, avoid locking when images fail to load and avoid paste frames onto frames ->>>>>>> main --- ## Metadata @@ -13,11 +9,7 @@ description: Fix to pan stage when dragging elements near border, avoid locking ### Fixed -<<<<<<< bugfix/GH-1044-nodes-dissapear-when-moving-b -- [#1038](https://github.com/InditexTech/weavejs/issues/1038) Avoid to add a frame inside a frame by pasting with right mouse button -======= - [#1036](https://github.com/InditexTech/weavejs/issues/1036) Corrupt Image nodes prevent frames to complete initial loading - [#1038](https://github.com/InditexTech/weavejs/issues/1038) Is possible to add a frame inside a frame by pasting with right mouse button ->>>>>>> main - [#1043](https://github.com/InditexTech/weavejs/issues/1043) Canvas does not auto-scroll when dragging an element near the border - [#1044](https://github.com/InditexTech/weavejs/issues/1044) Nodes disappear when moving between frames From 56ee88540ae18b2461b3b4d48297fd06319c6e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Mon, 11 May 2026 13:38:46 +0200 Subject: [PATCH 07/12] chore: fix async lock when imageURL is undefined --- code/packages/sdk/src/nodes/image/image.ts | 98 +++++++++++++--------- 1 file changed, 60 insertions(+), 38 deletions(-) diff --git a/code/packages/sdk/src/nodes/image/image.ts b/code/packages/sdk/src/nodes/image/image.ts index d064019bb..e2861df2b 100644 --- a/code/packages/sdk/src/nodes/image/image.ts +++ b/code/packages/sdk/src/nodes/image/image.ts @@ -983,15 +983,21 @@ export class WeaveImageNode extends WeaveNode { ): void { const imageURLToLoad = imageURL ?? 'http://localhost/false-image'; + if (imageURLToLoad === '') { + console.log('AQUI'); + this.setErrorState(imageId, undefined); + return; + } + this.imageSource[imageId] = Konva.Util.createImageElement(); this.imageSource[imageId].crossOrigin = this.config.crossOrigin; this.imageSource[imageId].onerror = (error) => { if (!loadingTryout) { - this.imageState[imageId] = { - status: 'error', - loaded: false, - error: true, - }; + const stage = this.instance.getStage(); + const image = stage.findOne(`#${imageId}`) as Konva.Group | undefined; + if (image) { + this.setErrorState(imageId, image); + } } onError(error); @@ -1074,6 +1080,7 @@ export class WeaveImageNode extends WeaveNode { if (node) { this.imageTryoutAttempts[id] = (this.imageTryoutAttempts[id] ?? 0) + 1; + this.loadImage( node.getAttrs(), node as Konva.Group, @@ -1167,37 +1174,30 @@ export class WeaveImageNode extends WeaveNode { }, onError: (error) => { if (!this.config.useFallbackImage) { - this.imageTryoutIds[id] = setTimeout(() => { - const node = this.instance.getStage().findOne(`#${id}`); + const tryoutAttempts = this.imageTryoutAttempts[id] ?? 0; - if (node) { - this.imageTryoutAttempts[id] = - (this.imageTryoutAttempts[id] ?? 0) + 1; - this.loadImage( - node.getAttrs(), - node as Konva.Group, - false, - true - ); - } - }, this.config.imageLoading.retryDelayMs); + if ( + tryoutAttempts - 1 < + this.config.imageLoading.maxRetryAttempts + ) { + this.loadImageTryout(id); + return; + } else { + this.setErrorState(id, image); + } } if (loadTryout) { const tryoutAttempts = this.imageTryoutAttempts[id] ?? 0; - if (tryoutAttempts < this.config.imageLoading.maxRetryAttempts) { - this.imageTryoutIds[id] = setTimeout(() => { - const node = this.instance.getStage().findOne(`#${id}`); - if (node) { - this.imageTryoutAttempts[id] = tryoutAttempts + 1; - this.loadImage( - node.getAttrs(), - node as Konva.Group, - false, - true - ); - } - }, this.config.imageLoading.retryDelayMs); + + if ( + tryoutAttempts - 1 < + this.config.imageLoading.maxRetryAttempts + ) { + this.loadImageTryout(id); + return; + } else { + this.setErrorState(id, image); } return; } @@ -1218,19 +1218,15 @@ export class WeaveImageNode extends WeaveNode { return; } - this.imageState[id] = { - status: 'error', - loaded: false, - error: true, - }; + this.setErrorState(id, image); image.setAttrs({ image: undefined, }); - this.resolveAsyncElement(id); + console.error('Error loading image', error); - console.error('Error loading image', realImageURL, error); + this.resolveAsyncElement(id); imagePlaceholder?.setAttrs({ visible: true, @@ -1438,4 +1434,30 @@ export class WeaveImageNode extends WeaveNode { nodeInstance.destroy(); } + + private loadImageTryout(imageId: string): void { + this.imageTryoutIds[imageId] = setTimeout(() => { + const node = this.instance.getStage().findOne(`#${imageId}`); + if (node) { + const tryoutAttempts = this.imageTryoutAttempts[imageId] ?? 0; + this.imageTryoutAttempts[imageId] = tryoutAttempts + 1; + + this.loadImage(node.getAttrs(), node as Konva.Group, false, true); + } + }, this.config.imageLoading.retryDelayMs); + } + + private setErrorState(imageId: string, image?: Konva.Group): void { + this.imageState[imageId] = { + status: 'loaded', + loaded: true, + error: true, + }; + + this.resolveAsyncElement(imageId); + + if (image) { + this.cacheNode(image); + } + } } From 211cc678e1fe1b1606551e3fe8f5ea0d5f8c88e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Mon, 11 May 2026 13:40:54 +0200 Subject: [PATCH 08/12] chore: fix async lock when imageURL is undefined --- code/packages/sdk/src/nodes/image/image.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/code/packages/sdk/src/nodes/image/image.ts b/code/packages/sdk/src/nodes/image/image.ts index e2861df2b..f03e699c7 100644 --- a/code/packages/sdk/src/nodes/image/image.ts +++ b/code/packages/sdk/src/nodes/image/image.ts @@ -984,7 +984,6 @@ export class WeaveImageNode extends WeaveNode { const imageURLToLoad = imageURL ?? 'http://localhost/false-image'; if (imageURLToLoad === '') { - console.log('AQUI'); this.setErrorState(imageId, undefined); return; } From 4729cb861e659dc06043acb98a734c96ac07b2e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Mon, 11 May 2026 13:42:07 +0200 Subject: [PATCH 09/12] chore: fix async lock when imageURL is undefined --- code/packages/sdk/src/nodes/image/image.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/packages/sdk/src/nodes/image/image.ts b/code/packages/sdk/src/nodes/image/image.ts index f03e699c7..3bffd5d74 100644 --- a/code/packages/sdk/src/nodes/image/image.ts +++ b/code/packages/sdk/src/nodes/image/image.ts @@ -984,7 +984,7 @@ export class WeaveImageNode extends WeaveNode { const imageURLToLoad = imageURL ?? 'http://localhost/false-image'; if (imageURLToLoad === '') { - this.setErrorState(imageId, undefined); + this.setErrorState(imageId); return; } @@ -993,9 +993,9 @@ export class WeaveImageNode extends WeaveNode { this.imageSource[imageId].onerror = (error) => { if (!loadingTryout) { const stage = this.instance.getStage(); - const image = stage.findOne(`#${imageId}`) as Konva.Group | undefined; + const image = stage.findOne(`#${imageId}`); if (image) { - this.setErrorState(imageId, image); + this.setErrorState(imageId, image as Konva.Group); } } From 1e682f85f2af945960adb49b9b257985e21d3736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Mon, 11 May 2026 14:15:58 +0200 Subject: [PATCH 10/12] fix: avoid images dissapear when image not loaded and is moved the node --- code/packages/sdk/src/nodes/image/image.ts | 23 +++------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/code/packages/sdk/src/nodes/image/image.ts b/code/packages/sdk/src/nodes/image/image.ts index 3bffd5d74..90a2900a3 100644 --- a/code/packages/sdk/src/nodes/image/image.ts +++ b/code/packages/sdk/src/nodes/image/image.ts @@ -264,8 +264,6 @@ export class WeaveImageNode extends WeaveNode { } onRender(props: WeaveElementAttributes): WeaveElementInstance { - // this.initGlobalEvents(); - this.setupNotUsedImagesCleanup(); // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -859,29 +857,12 @@ export class WeaveImageNode extends WeaveNode { } // Loaded but image is corrupted if (this.imageState[id ?? '']?.loaded && this.imageState[id ?? '']?.error) { - imagePlaceholder?.setAttrs({ - ...internalImageProps, - ...(nodeAttrs.imageProperties ?? {}), - name: undefined, - id: `${id}-placeholder`, - nodeId: id, - x: 0, - y: 0, - scaleX: 1, - scaleY: 1, - rotation: 0, - visible: true, - fill: this.config.style.placeholder.fill, - strokeWidth: 0, - draggable: false, - zIndex: 0, - }); internalImage?.setAttrs({ ...internalImageProps, ...(nodeAttrs.imageProperties ?? {}), name: undefined, id: `${id}-image`, - image: undefined, + image: this.imageFallback[id ?? ''], nodeId: id, x: 0, y: 0, @@ -892,6 +873,8 @@ export class WeaveImageNode extends WeaveNode { draggable: false, zIndex: 1, }); + internalImage?.visible(true); + this.updateImageCrop(nodeInstance as Konva.Group); } // Loaded if ( From f0315ef8879adaa4e09f04a17be54d580b3cc3a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Mon, 11 May 2026 14:43:16 +0200 Subject: [PATCH 11/12] chore: cherry pick change to avoid ctrlKey when doesnt exist on mouse event --- code/packages/sdk/src/nodes/node.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/packages/sdk/src/nodes/node.ts b/code/packages/sdk/src/nodes/node.ts index 97814109f..915374637 100644 --- a/code/packages/sdk/src/nodes/node.ts +++ b/code/packages/sdk/src/nodes/node.ts @@ -1053,10 +1053,10 @@ export abstract class WeaveNode implements WeaveNodeBase { } handleMouseout(e: KonvaEventObject, node: Konva.Node) { - const isCtrlOrMetaPressed = e.evt.ctrlKey || e.evt.metaKey; + const isCtrlOrMetaPressed = e.evt?.ctrlKey || e.evt?.metaKey; if (isCtrlOrMetaPressed) { - return; + return false; } const realNode = this.instance.getInstanceRecursive(node); From 100728f765cacf19723aea0518abc14b2363a15f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Mon, 11 May 2026 15:30:30 +0200 Subject: [PATCH 12/12] chore: update docs --- .../sdk/src/plugins/copy-paste-nodes/types.ts | 7 ++++++- .../plugins/copy-paste-nodes.mdx | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/code/packages/sdk/src/plugins/copy-paste-nodes/types.ts b/code/packages/sdk/src/plugins/copy-paste-nodes/types.ts index ab2dae12b..5ad6d57dc 100644 --- a/code/packages/sdk/src/plugins/copy-paste-nodes/types.ts +++ b/code/packages/sdk/src/plugins/copy-paste-nodes/types.ts @@ -61,8 +61,13 @@ export type PaddingOnPaste = { paddingY: number; }; +export type WeaveCanPasteOntoFunction = ( + node: WeaveStateElement, + atTarget: Konva.Container +) => boolean; + export type WeaveCopyPasteNodesPluginConfig = { - canPasteOnto: (node: WeaveStateElement, atTarget: Konva.Container) => boolean; + canPasteOnto: WeaveCanPasteOntoFunction; paddingOnPaste: PaddingOnPaste; }; diff --git a/docs/content/docs/sdk/api-reference/plugins/copy-paste-nodes.mdx b/docs/content/docs/sdk/api-reference/plugins/copy-paste-nodes.mdx index eca3bbf1f..fdf788344 100644 --- a/docs/content/docs/sdk/api-reference/plugins/copy-paste-nodes.mdx +++ b/docs/content/docs/sdk/api-reference/plugins/copy-paste-nodes.mdx @@ -49,6 +49,15 @@ const WEAVE_COPY_PASTE_PASTE_MODES = { } as const; const WEAVE_COPY_PASTE_CONFIG_DEFAULT = { + canPasteOnto: (node: WeaveStateElement, atTarget: Konva.Container) => { + const targetType = atTarget.getAttrs().nodeType; + + if (targetType === "frame" && node.type === "frame") { + return false; + } + + return true; + }, paddingOnPaste: { enabled: false, paddingX: 0, @@ -90,7 +99,13 @@ type PaddingOnPaste = { paddingY: number; }; +export type WeaveCanPasteOntoFunction = ( + node: WeaveStateElement, + atTarget: Konva.Container, +) => boolean; + type WeaveCopyPasteNodesPluginConfig = { + canPasteOnto: WeaveCanPasteOntoFunction; paddingOnPaste: PaddingOnPaste; }; @@ -122,6 +137,12 @@ For `WeaveCopyPasteNodesPluginConfig`: