Browse Source

update getStateSnapshot behavior (#858)

* update getStateSnapshot behavior

* update syncCurrent
David Sehnal 1 year ago
parent
commit
0ee8525b2d
2 changed files with 18 additions and 7 deletions
  1. 1 0
      CHANGELOG.md
  2. 17 7
      src/mol-plugin-state/manager/snapshots.ts

+ 1 - 0
CHANGELOG.md

@@ -7,6 +7,7 @@ Note that since we don't clearly distinguish between a public and private interf
 ## [Unreleased]
 
 - Fix display issue with SIFTS mapping
+- Update `getStateSnapshot` to only overwrite current snapshot if it was created automatically
 - Fix distinct palette's `getSamples` infinite loop
 - Add 'NH2', 'FOR', 'FMT' to `CommonProteinCaps`
 - Add `opened` event to `PluginStateSnapshotManager`

+ 17 - 7
src/mol-plugin-state/manager/snapshots.ts

@@ -29,6 +29,7 @@ class PluginStateSnapshotManager extends StatefulPluginComponent<{
     static DefaultNextSnapshotDelayInMs = 1500;
 
     private entryMap = new Map<string, PluginStateSnapshotManager.Entry>();
+    private defaultSnapshotId: UUID | undefined = undefined;
 
     readonly events = {
         changed: this.ev(),
@@ -67,6 +68,8 @@ class PluginStateSnapshotManager extends StatefulPluginComponent<{
         const old = this.getEntry(id);
         if (!old) return;
 
+        this.defaultSnapshotId = undefined;
+
         if (old?.image) this.plugin.managers.asset.delete(old.image);
         const idx = this.getIndex(old);
         // The id changes here!
@@ -172,20 +175,27 @@ class PluginStateSnapshotManager extends StatefulPluginComponent<{
     }
 
     private async syncCurrent(options?: { name?: string, description?: string, params?: PluginState.SnapshotParams }) {
+        const isEmpty = this.state.entries.size === 0;
+        const canReplace = this.state.entries.size === 1 && this.state.current && this.state.current === this.defaultSnapshotId;
+
+        if (!isEmpty && !canReplace) return;
+
         const snapshot = this.plugin.state.getSnapshot(options?.params);
-        if (this.state.entries.size === 0 || !this.state.current) {
-            this.add(PluginStateSnapshotManager.Entry(snapshot, { name: options?.name, description: options?.description }));
-        } else {
+        const image = (options?.params?.image ?? this.plugin.state.snapshotParams.value.image) ? await PluginStateSnapshotManager.getCanvasImageAsset(this.plugin, `${snapshot.id}-image.png`) : undefined;
+
+        if (isEmpty) {
+            this.add(PluginStateSnapshotManager.Entry(snapshot, { name: options?.name, description: options?.description, image }));
+        } else if (canReplace) {
+            // Replace the current state only if there is a single snapshot that has been created automatically
             const current = this.getEntry(this.state.current);
             if (current?.image) this.plugin.managers.asset.delete(current.image);
-            const image = (options?.params?.image ?? this.plugin.state.snapshotParams.value.image) ? await PluginStateSnapshotManager.getCanvasImageAsset(this.plugin, `${snapshot.id}-image.png`) : undefined;
-            // TODO: this replaces the current snapshot which is not always intended
-            this.replace(this.state.current, snapshot, { image });
+            this.replace(this.state.current!, snapshot, { image });
         }
+
+        this.defaultSnapshotId = snapshot.id;
     }
 
     async getStateSnapshot(options?: { name?: string, description?: string, playOnLoad?: boolean, params?: PluginState.SnapshotParams }): Promise<PluginStateSnapshotManager.StateSnapshot> {
-        // TODO: diffing and all that fancy stuff
         await this.syncCurrent(options);
 
         return {