TiddlyWiki / TiddlyWiki5

A self-contained JavaScript wiki for the browser, Node.js, AWS Lambda etc.
https://tiddlywiki.com/
Other
7.97k stars 1.18k forks source link

recycle bin / undo edits #2030

Closed tobibeer closed 1 year ago

tobibeer commented 8 years ago

just now I deleted 5 minutes of typing for not paying attention ...so, a recycle bin for the last X deleted tiddlers or so would be really neat

inmysocks commented 8 years ago

I like this idea. A straight forward implementation could just change the delete button to add some prefix like $:/recyclebin/ and have part of the delete button function to delete the oldest tiddler after x have been put there.

There could be weirdness if you try to delete a tiddler that already has the $:/recyclebin/ prefix, but I guess having $:/recyclebin/$:/recyclebin/ as a prefix doesn't break anything.

But yes, I really like this idea.

tobibeer commented 8 years ago

Let's see if we can't create a demo. ;-)

Jermolene commented 8 years ago

One would expect that a deleted tiddler would end up in the recycle bin, but what if I edit a tiddler and delete a field; should that tiddler also go into the recycle bin? Or what if I purposely overwrite one tiddler with another; should the overwritten one go into the recycle bin?

tobibeer commented 8 years ago

but what if I edit a tiddler and delete a field; should that tiddler also go into the recycle bin?

I guess there are two ways to go about it...

  1. undo — allows me to do just a given, well defined action, e.g. "change field back to"
  2. recycle bin — works like on your computer, it's got stuff in it you can restore, not the state of stuff

Perhaps undoing is actually the favorable approach in a wiki, because...

  1. You can clearly indicate the kind of change you will undo, perhaps even review things before you do...
  2. it's more granular
  3. it also catches the big actions, e.g. "delete", overwrite, etc...

Or what if I purposely overwrite one tiddler with another; should the overwritten one go into the recycle bin?

If at all, I would allow to restore that tiddler to a safe name, e.g. "My Tiddler (1)" and open it for review. So, undoing or restoring would not necessarily mean to undo exactly what you did there, but rather to be able to get back to those content-bits, perhaps.

Should possibly not be temp tiddlers, because we might want test some changes we made after reload and only then we recognize an issue.

So, it could be like a "commit history" for those type of events / actions for which there is a restore / undo method defined. Perhaps the core could just provide a framework for all that / a basic "undelete" action with the rest being extensible via plugin modules that mimick / hook into things in a similar way.

pmario commented 8 years ago

TLDR; I like the idea of an undo function or a recycle bin. ... but ... it should be non persistent by default.


We had to remove the $:/HistoryList tiddler from saving, since it made TWs too big. see: $:/core/save/all

So imo nobody really wants that much bloat saved in TWs.

We also have the same privacy problem, that was discussed as TiddlySpace introduces public and private tiddlers (not) including the history.

eg: I create a PrivateInfo tiddler with the content My boss sucks. I delete this tiddler, save it. Some time later I need to send it per mail to the boss. s/he opens the recycle bin and restores the PrivateInfo tiddler. ...

tobibeer commented 8 years ago

An undo feature could be deactive by default and if enabled it would be very much obvious that there is a history being saved. It's a feature not a security threat. If someone needed to purge such a history, a simple button will do.

Whether or not these data are persisted should be for the user to decide (depending on the namespace being used), e.g.:

title: $:config/namespace/undo

$:/temp/undo/
sukima commented 8 years ago

Instead of looking at it in the idea of a recycle bin how about snap shots like Git does versioning.

Each time there is a change the system takes a holistic snapshot. This way you could undo or travel back in time if you need to. Overwrite a tiddler makes a new snapshot. Go back on snapshot and it's back. You could keep the 5 latest snapshots or allow a user to garbage collect old snapshots.

Kinda like this: https://schacon.github.io/gitbook/1_the_git_object_model.html

tobibeer commented 8 years ago

@sukima, let's think practical

a basic undo feature is a thing of a day or two, more or less...

the nice Idea you're talking about is a thing of a year or two for a team of devs :D

what's more, we can already do this with TW on node.js... leveraging the power of both systems, github and tw, each with their own strengths and weaknesses

pmario commented 8 years ago

It's a feature not a security threat.

I was talking about a privacy issue, not a security problem. But storing and recycling tiddlers with sensitive content, could be exactly that.

inmysocks commented 8 years ago

I think it would be reasonable to give the recycle bin a limited life span. When saving the wiki there could be a check on when the tiddler was deleted and if it has been more than x days/hours to delete them permanently. That wouldn't be hard to implement and would be a desirable feature for reasons other than privacy as well.

tobibeer commented 8 years ago

I think a mix of these may be optimal...

  1. max-#-undo-entries / max-#-items-in-the-restore-bucket, e.g. 10 tiddlers / records
    • possibly even restrict max bin-(/file-)size (rough guestimate: num characters)
  2. auto-purge older than x days

Older than x may be too generous with frequent edits while keeping x records might end up keeping really old items for sparse edits. So, the trade-off could/would be: do both.

If a user enabled only a per-session-undo-history, 2. would be irrelevant and the file-size considerations for 1. as well. So, perhaps the best start might be to just provide a session-undo-feature and see if there's actually anyone who'd crave more than that, so...

inmysocks commented 8 years ago

That sounds like a good way to do it. I don't think that we should necessarily make this 'undo' in the sense that deleting a field could be recovered, just a recycle bin for deleted tiddlers. An undo function that could restore deleted fields would be very nice but I think it would have a completely different implementation. Something like a data tiddler that holds the field tiddler name, field name and field contents of the previous x deleted or modified fields, with the same logic about what to retain as Tobias suggested.

pmario commented 8 years ago

I think a simple "time out" recycle bin could be the first option, that could go a long way for users. ...

Jeremy mentioned a "diff- patch- merge" approach, that he is interested in. So this could be a future improvement for a undo history.

sukima commented 8 years ago

I know I went on a limb with suggesting changing the underlying data store. But I am still adamant that a "diff- patch- merge" approach would provide more flexibility then a simple recycle bin. Simply as a tiddler saves it's previous state is saved to $:/snapshots/ or $:/oldversions/ then restoring is simply a matter of applying the diff in reverse. Or in the case of a snapshot, replacing the tiddler. There are a few good JavaScript diff libraries out there. A simple patch display could be used to show the tiddler with red and green highlighted sections to show what was changed between each snapshot and/or show the user what would happen if they restored the tiddler.

I'm just trying to keep the big picture (holistic) view open. I'm concerned by focusing on the Recycle bin concept only that blinders could produce an implementation that is a one off solution that doesn't scale well. By approaching the problem domain with an eye to the bigger picture the solution can often times be more elegant and flexible providing a foundation for future features that otherwise would not be available with a more focused solution. I think my experience working with SubVersion vs Git has shown me that the choice of implementation had far reaching effects on how flexible and versatile a software is. With SubVersion (although solves the same problem as Git) I can not do nearly 80% of the things I can do with Git. And it just has to do with how the two system approached the same problem domain.

inmysocks commented 8 years ago

The main reason I like the recycle bin and undo solution is that I know how it can be implemented. I have no idea how to implement a git-like versioning system. I agree that it would be a better solution if it can be done. I don't think that making the simpler option will prevent a better solution in the future since it would only take some changes to the delete buttons and a new revert or undelete button.

I do think that a git-like versioning system could introduce a lot of weird edge cases but that may just be me worrying too much.

pmario commented 8 years ago

There are a few good JavaScript diff libraries out there.

I also would prefer an undo functionality. But imo the problem isn't to create incremental diffs from a tiddler. IMO it's managing the diffs. As you point out. GIT is very different to SubVersion eg:

If we think about commits (snapshots), diffs and so on, we (at leat me) expect a similar functionality like git. I'm sure, we can't deliver a similar experience in a single file TW. That's why. If I need git like functionality, I use git.

That's also a reason, why all this stuff should be plugins and not core.

sukima commented 8 years ago

Yeah good points @pmario and @inmysocks.

“Shoot for the moon. Even if you miss, you'll land among the stars.” ― Norman Vincent Peale

pmario commented 8 years ago

“Shoot for the moon. Even if you miss, you'll land among the stars.” ― Norman Vincent Peale

yea. That's why I liked your passionate post :)

tobibeer commented 8 years ago

Or in the case of a snapshot, replacing the tiddler.

I think that is the very first and basic concept that will perhaps get implemented, e.g. an undo message above a tiddler upon saving that simply...

I do think that a git-like versioning system could introduce a lot of weird edge cases but that may just be me worrying too much.

If anything, I think that's a reasonable expectation ;-)

Jermolene commented 8 years ago

Conceivably there are two discussions here: the technicalities of how to retain overwritten changes and deletions, and the user interface for allowing users to roll back their changes.

As @pmario mentioned, I'm interested in using diff trees to be able to store a full version history. I don't think there's much difficulty in the implementation - see this, for instance: https://github.com/creationix/js-git

As far as the UI is concerned, I'd have to agree that a recycle bin has the attraction of being a common, familiar user interface.

pmario commented 8 years ago

I don't think there's much difficulty in the implementation - see this, for instance: https://github.com/creationix/js-git

I haven't noticed this project. thx for sharing. So we can delete one of my concerns. ... great :)

pmario commented 1 year ago

There is the Trash-bin plugin from kookma ... https://kookma.github.io/TW-Trashbin/ which imo can handle the OP well enough. The https://tiddlywiki.com/#SaveTrail%20Plugin may be an option too and there is https://yaisog-patches.tiddlyhost.com/ which uses the core diff-match-patch tools to save tiddler revisions. See: https://yaisog-patches.tiddlyhost.com/#%24%3A%2Fplugins%2Fyaisog%2Fpatches%2FViewer

@Jermolene ... IMO we can close this one

Jermolene commented 1 year ago

Thanks @pmario