whitebophir icon indicating copy to clipboard operation
whitebophir copied to clipboard

undo / redo feature

Open anjanappadg opened this issue 4 years ago • 18 comments

Hi, Thanks for whitebophir, we are planning to implement undo / redo functionality using Undomanager library. What is best place to implement undo/redo on client side / server side. Thanks

anjanappadg avatar Aug 06 '20 14:08 anjanappadg

Hello ! Undo/redo would be a very interesting and useful, but quite difficult to implement feature. You would need to change every tool to add a function that undoes a given message, and then call this function from the board manager.

lovasoa avatar Aug 11 '20 17:08 lovasoa

Thanks @lovasoa, we will follow the same to implement Undo / Redo .

anjanappadg avatar Aug 12 '20 05:08 anjanappadg

Good afternoon, I am working on this tool, I changed all the tools, everything works correctly except for returning the pencil after deleting. Example: before deletion image

After recovery: image

I checked all the socket messages, restoring the pencil is 100% the same as the previous drawing requests, but gives different results, and after refreshing the page, the pencil again becomes correct as it was before deletion. I don’t know how to fix this problem, I can make a separate pull request if needed

shabashev-ivan avatar Aug 14 '20 11:08 shabashev-ivan

@shabashev-ivan, even i faced same problem for pencil. this issue got resolved after clearing pathDataCache data.

in draw function just add - pathDataCache[data.id] = ""

                  switch (data.type) {
		case "line":
			renderingLine = createLine(data);
                             pathDataCache[data.id] = ""
			break;

anjanappadg avatar Aug 14 '20 11:08 anjanappadg

@anjanappadg Thank you very much for the help! I spent ~ 8 hours debugging and couldn't find this one. It turned out to be so easy that I am ashamed (

shabashev-ivan avatar Aug 14 '20 12:08 shabashev-ivan

No Problem @shabashev-ivan even i spent more than one day :(

anjanappadg avatar Aug 14 '20 12:08 anjanappadg

Don't be afraid to open a pull request now even if the feature is not ready yet. The earlier we can start discussing the code, the easiest it will be to have it merged when it's ready.

lovasoa avatar Aug 14 '20 12:08 lovasoa

@shabashev-ivan may I friendly ask what the status is of this code? I see in your forked repos you have done many enhancements, are you planning to upstream those? Just asking, thx :+1:

heyleke avatar Jan 18 '21 09:01 heyleke

@ shabashev-ivan, могу я по-дружески спросить, каков статус этого кода? Я вижу, что в ваших разветвленных репозиториях вы сделали много улучшений, планируете ли вы их апстрим? Просто спрашиваю, спасибо👍

I do not have time for this, there are also too many changes there to simply transfer them to the original repository, but I think you can easily take the functions you need, refactor them and push to the repository, if you just want to try my changes, then you can raise the database (mongoDB), install the dev mod in the .env file. Then create a board and connect to it. If you have any problems, you can write to me, I will help you solve them

shabashev-ivan avatar Jan 18 '21 20:01 shabashev-ivan

@lovasoa Hi,Thanks for your answer, whitebophir is a nice tool I used,Now I have some free time to implement this feature.But I have no idea about how you plan to do. In my option,I tend to implement a history list, like many software we can recover one history action, press 'CTRL +Z' or click menu.We can implement it on client browser, that saved history list in JS storage and call server interface. Its a rough idea,So I hope you can give me some suggestions or some ideas.thx 💯

willerhe avatar Jun 13 '21 03:06 willerhe

@willerhe you can look at this code, this function is implemented here, but the code is terrible https://github.com/sboard-team/whitebophir/blob/master/client-data/js/board.js example of using: https://github.com/sboard-team/whitebophir/blob/master/client-data/tools/pencil/pencil.js Tools.addActionToHistory({type: "delete", id: curLineId});

shabashev-ivan avatar Jun 13 '21 06:06 shabashev-ivan

@shabashev-ivan OK. Thanks very much for talking to me.

willerhe avatar Jun 14 '21 11:06 willerhe

Hi, I am currently motivated to try to implement undo/redo. I don't have much experience in javascript really, but maybe I can still give it a try. @lovasoa, do you think it is really best to implement the undo/redo in the tools, and not maybe in the server? I haven't completely understood the code of the whiteboard yet, nor have I looked at other peoples implementations of undo/redo, but here are my thoughts:

  • If we do it on the server then maybe we don't need to touch each tool separately.
  • We need the history about in which order also other users have written on the whiteboard in order to deal with the following cases. And my feeling is that it should be enough if this history is stored on the server, and not sent to every client.
  1. client1 creates an object, client2 edits it, and then client1 presses undo.
  2. client1 draws a line1, client2 draws line2 on top, client1 does undo, client1 does redo. I think in this case we would eventually want line1 to end up below line2 again.

How about storing a list of edits edit1 … editN on the server, with each edit containing the information which client has performed which edit, and then when a client1 wants to undo, we find its latest edit, say editK, we undo all edits editK up to editN, and then replay edit(K+1) up to editN, unless some of the edits between edit(K+1) and editN changes an object that has been changed in editK, in which case we do whatever we decide to do in that case.

I now realized that for the above plan to work, on first has to define what counts as one edit. This probably should happen in each tool. I see this is getting back towards implementing undo in the client…

julianuu avatar Jul 30 '21 09:07 julianuu

This is the idea, lots of things still missing https://github.com/julianuu/whitebophir

julianuu avatar Jul 30 '21 14:07 julianuu

I implemented something along the lines of what I wrote above. It doesn't work completely yet on the server side, but what I realized now is that the way data is sent to the clients is via tools. That means if it stays like this, then indeed undo has to be written specifically for any tool.

julianuu avatar Aug 23 '21 17:08 julianuu

I implemented something along the lines of what I wrote above. It doesn't work completely yet on the server side, but what I realized now is that the way data is sent to the clients is via tools. That means if it stays like this, then indeed undo has to be written specifically for any tool.

I wanted to thank you for working on this. I really wish there was more I can do but I don't have enough experience. I really appreciate you trying, it sounds really difficult. Hope it gets figured out soon....

Zzisx avatar Sep 13 '21 22:09 Zzisx

I wanted to thank you for working on this. I really wish there was more I can do but I don't have enough experience. I really appreciate you trying, it sounds really difficult. Hope it gets figured out soon....

Greatly appreciated! I got a little busy these days, I'll try to continue in the next weeks. I'm also a bit unsure how to proceed, because my approach seems to require a reorganization of some things. I also have close to zero experience ;)

julianuu avatar Sep 16 '21 17:09 julianuu

Hi @lovasoa, what do you think about rewriting the data for drawing that is sent from the server to the the client to be not tool-based? Instead let the communicated messages have content {"category":"add", "type":"rectangle", "id":123, …} and forget about which tool makes them. This feels a bit more flexible to me, and would make the above idea for a server-based undo easier to implement I think. Then an undo of a "delete"-category message would just be an "add" message, and we would not need to find the correct tool for that.

julianuu avatar Sep 21 '21 07:09 julianuu