Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature request: optionally cancelling adding to the stack #8

Closed
Xananax opened this issue Feb 1, 2022 · 5 comments
Closed

feature request: optionally cancelling adding to the stack #8

Xananax opened this issue Feb 1, 2022 · 5 comments
Labels
enhancement New feature or request

Comments

@Xananax
Copy link

Xananax commented Feb 1, 2022

Sometimes, a user does an operation that triggers a function, but the operation turns out to be invalid, and state is unchanged (at least, as far as a user can tell).

For example, in my application, items can be added in arbitrary positions on a canvas, but they are only valid depending on specific rules. Because I need to loop over a prohibitively large amount of objects, I am reluctant to do a verification pass, then an update pass; I do both at the same time. So the function is what goes in Undo's execute, whether it leads to a meaningful change or not.

In those cases, enabling the undo button is confusing, and pressing it does nothing that the user can see or care about.

if the line https://github.com/rodydavis/undo/blob/master/lib/src/undo_stack.dart#L20 allowed the following:

  void add<T>(Change<T> change) {
    final bool? response = change.execute();
    if(response == false){ 
      return;
     }
    _history.addLast([change]);
    _moveForward();
  }

Then one could optionally return false from the execute function, which would solve my problem.

Line https://github.com/rodydavis/undo/blob/master/lib/src/undo_stack.dart#L88 would need to be changed thusly:

final bool? Function() _execute;

None of those changes break any backwards compatibility, and they make things more convenient.

Passing lambdas works, but typed named void functions don't, so it is backward compatibility breaking. dynamic works, I'm not acquainted with Dart enough to know if something else works better.

Then, one could write:

changes.add(Change(
  data, 
  (){
     try{
      attemptInsertData();
      return true;
     }catch(e){
      return false;
    }
  }, 
  (old) => data = old
  ));

If you like this change, I can create a PR.

@Xananax
Copy link
Author

Xananax commented Feb 1, 2022

My workaround at the moment is the following:

changes.add(Change(
  data, 
  (){
     try{
      attemptInsertData();
     }catch(e){
       await Future.delayed(const Duration(milliseconds: 1), () {
         changes.undo();
       });
    }
  }, 
  (old) => data = old
  ));

Not the most elegant, but it works

@rodydavis
Copy link
Owner

I am going to add the try/catch method!

@rodydavis rodydavis added the enhancement New feature or request label Dec 2, 2023
@rodydavis
Copy link
Owner

Fixed on v1.5.0

@rodydavis
Copy link
Owner

I implemented it by throwing an exception and the application can handle the error but it will not insert.

If there was and error you could undo if needed

@Xananax
Copy link
Author

Xananax commented Dec 2, 2023

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants