Hello!
I have a use case which I cannot seem to find specific resources on, if you feel like there are some similar issues somewhere, please feel free to share.
I am building a tool, where I spawn multiple editors. Essentially, user can add new rows, where each row includes an Editor View. Something like a Code Notebook.
I have some non-editor related state, which I managed to integrate with Undo History just fine, using State Effects. My set up is a “root” Editor State, with a State Field which holds a map of so called Segments. Each Segment holds some non-editor properties, as well as their own state with an Editor View. Each Segments corresponds to a row I mention. My non-editor operations, such as adding or removing Segments are working with the Undo History as expected.
What I am trying to achieve, is a common Undo History state for all Segment’s Editor Views, as well as the non-editor related state. I’ve tried to follow the “Split View” example, but since it talks about Views that are in complete sync, I cannot really apply it to my use case. I don’t want each Editor View to have the same state, but have a common Undo History.
Desired result is basically like this:
User Adds new Segment →
Types “foo” in it →
Adds new Segment again →
types “bar” in it →
Undos → “bar” text gets undone →
Undos again →
“bar” Segment gets removed →
Undos again →
“foo” text gets undone →
Undos again →
“foo” segment gets removed
The add/remove operations work already, as I described. The problem are the changes in each editor, how to append them to the “root” state and how to reverse them in the specific editor once undo is triggered.
Following the Split View example, I pass each Segment a “sync” function, that its View uses in dispatch method. Instead of dispatching the change to other Views as in the example, I update the “root” state with an effect that includes the transaction and the corresponding ID of the Segment. This is where it stops, because it feels like utilising “invertedEffects” to manually reverse changes is kind of re-implementing Undo History extension’s logic.
Feels like I am close there, but is the solution really to update the “root” state with a State Effect including the changes and the ID of the editor it corresponds to and use “invertedEffects” with a State Effect that reverses the changes? If so, what is the best way to do it? Save the transaction in initial effect and add a reverse effect, that when triggered, applies the inverted change of the initial transaction somehow?