I also have a new repro (slightly different than the original one, but in a similar vein) that shows that this isnāt fixed.
On the web:
- Create item with one child and collapse (Foo -> Bar).
- Go offline (dev tools -> network).
- Zoom in and delete the child item.
- Zoom out and add a new child item āBazā. The item will be uncollapsed.
- In a new tab, zoom into the item and add a second item āQuxā.
- Reconnect the first client and sync up.
- Verify the reconnected client is uncollapsed, while all other clients are still collapsed (even though all clients do show the proper child items āBazā and āQuxā).
Iām guessing that in this recent update thereās some tentatively_collapsed
state thatās kept for nodes with deleted children that havenāt synced up yet, is that correct? But when you add a new child item zoomed out the client āknowsā that it is no longer collapsed, leading us back to the original bug. This type of logic likely also explains the other issue I reported one post above.
In this case I actually think it makes more sense for the server-side state to be āuncollapsedā if weāre following a ālast-write-winsā model. This is made trickier by the fact that we donāt want to uncollapse items if they only became empty (no new children added), like in the original repro.
Hereās an idea for what might fix this: For each node that experiences a collapse state change keep track of the following (clearing out this state after a sync occurs):
- The last synced collapse state for the node.
- The current collapse state for the node (e.g. if you explicitly uncollapsed the item OR deleted all children, it is uncollapsed).
- Whether the collapse state change is tentative or definite. An explicit collapse/uncollapse is a definite change, whereas an item becoming uncollapsed due to all children being deleted is tentative. Adding the first child to an item is also a definite change (since the item is now visibly uncollapsed).
If a change is tentative, after a sync it should apply the following state changes (in this order of precedence):
- Any new collapse state changes synced down for that node.
- The last synced collapse state for the node.
If a change is definite, it should override any collapse state changes it sees and sync up its collapse state to the server (last-write-wins).
(this also relies on the server side explicitly setting nodes without any children as āuncollapsedā, including bumping the user version number when this occurs. I think this was the old behavior, but after the update this seems to have changed.)
It looks like the current solution is doing something like 1 and 2, but maybe itās missing the 3rd part?
If we follow this new model, then the above repro should result in the server-side incrementing the user version number, and forcing all other clients to be uncollapsed. For the original repro, the reconnecting clientās change would only be tentative, so once it resyncs it would re-apply the original collapse state it had for the item (collapsed), which would make it consistent with the other clients.