Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/clear-turkeys-relax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@viamrobotics/motion-tools': patch
---

Fix: add fragment-defined component names to the parent options in the details panel
5 changes: 5 additions & 0 deletions .changeset/yummy-ideas-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@viamrobotics/motion-tools': patch
---

Fix: Hold the staged frame pose in embedded mode while the framesystem reconfigures
14 changes: 14 additions & 0 deletions src/lib/hooks/useConfigFrames.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,20 @@ export const provideConfigFrames = () => {

const getParentFrameOptions = (componentName: string) => {
const validFrames = new Set(frameValues.map((frame) => frame.referenceFrame))

/**
* Fragment components without a mod don't appear in frameValues (we only
* track frames with explicit $set mods), but the fragment itself supplies
* their frame so they render in the scene and are valid parents. Exclude
* any whose frame the user has $unset.
*/
const unsetFragmentNames = new Set(fragmentUnsetFrameNames)
for (const name of Object.keys(partConfig.componentNameToFragmentId)) {
if (!unsetFragmentNames.has(name)) {
validFrames.add(name)
}
}

validFrames.add('world')

const frameNameQueue = [componentName]
Expand Down
45 changes: 42 additions & 3 deletions src/lib/hooks/usePartConfig.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,44 @@ interface AppEmbeddedPartConfigProps {
}

const useEmbeddedPartConfig = (props: AppEmbeddedPartConfigProps): LocalPartConfig => {
let hasPendingSave = $state(false)
let prevIsDirty = false
let cleanSnapshot: string | undefined

const snapshot = (current: Struct | undefined): string | undefined => {
const json = current?.toJson?.()
return json === undefined ? undefined : JSON.stringify(json)
}

/**
* The host app owns saving, and we aren't notified directly. Set hasPendingSave
* to watch isDirty: true -> false transitions, representing a save.
*
* `useFrames` clears the flag on the next `revision` change
* once the server reports the new framesystem.
*/
$effect.pre(() => {
const dirty = props.isDirty
const current = props.current

if (prevIsDirty && !dirty) {
const next = snapshot(current)
if (next !== undefined && cleanSnapshot !== undefined && next !== cleanSnapshot) {
hasPendingSave = true
}
cleanSnapshot = next
} else if (!prevIsDirty && !dirty) {
cleanSnapshot = snapshot(current)
}

prevIsDirty = dirty
})

return {
hasEditPermissions: true,
hasPendingSave: false,
get hasPendingSave() {
return hasPendingSave
},
get isDirty() {
return props.isDirty
},
Expand All @@ -327,8 +362,12 @@ const useEmbeddedPartConfig = (props: AppEmbeddedPartConfigProps): LocalPartConf
return props.setLocalPartConfig(struct)
},

clearPendingSave() {},
setPendingSave() {},
clearPendingSave() {
hasPendingSave = false
},
setPendingSave() {
hasPendingSave = true
},
}
}

Expand Down
Loading