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

More on Time Travel (undo/redo) #38

Closed
DonnC opened this issue Feb 4, 2021 · 10 comments
Closed

More on Time Travel (undo/redo) #38

DonnC opened this issue Feb 4, 2021 · 10 comments

Comments

@DonnC
Copy link

DonnC commented Feb 4, 2021

Hello @xamantra i have looked at the listify example and the documentation, it looks like time-travel works best with TextFields is there a way it can work for other models

Imagine a scenario:
I add my todos which are in a list just like listify example, but i want to do undo and redo on my todos when i delete a particular todo in my list of todos and not on text fields like what the example listify is doing
Is this possible with momentum's time travel?

@xamantra
Copy link
Owner

xamantra commented Feb 5, 2021

It is possible!
Undo/redo is commonly used for text fields but is not limited to it.

Example:

// imagine this function being called from a "Delete" button
void deleteItem() {
  // delete code logic here ...
  model.update(list: updatedList);
}

// imagine this function being called from an "Undo" button.
void undo() {
  this.backward(); // very simple. or just "backward();" without "this."
}

// can even redo the undo.
void undo() {
  this.forward();
}

@DonnC
Copy link
Author

DonnC commented Feb 5, 2021

I tried implementing that approach but i didnt see any change: Here is my cart controller with backward() & forward()
cart
and this is how i configured my main()
main
And this is my cart page, i commented that line because it wasnt working the way i expected, and if i uncomment, still i got a behaviour i didnt expect
page

And on home page i have the undo & redo buttons like this
redo-buttons

and my final cart UI is like this
ui

please help, what am i doing wrong in order to perform undo and redo

@xamantra
Copy link
Owner

xamantra commented Feb 5, 2021

@DonnC I want to know how you are referencing _cartModel in the 4th screenshot. Is it from a snapshot()?

@DonnC
Copy link
Author

DonnC commented Feb 5, 2021

Yes its from MomentumBuilder snapshot

@xamantra
Copy link
Owner

xamantra commented Feb 5, 2021

@DonnC I was able to reproduce undo/redo not working and I know the reason why. But before offering a possible solution. I want to know more about your deleteCartProduct() function in the 1st screenshot.

  • What type is = model.cart, is it a list?
  • If it is an object that holds a list instead, can you show me how you are actually removing the item?
  • Ignoring undo/redo, does the delete function actually work?

@xamantra
Copy link
Owner

xamantra commented Feb 5, 2021

  void addNewItem() {
    var list = List<String>.from(model.list); // proper way to manipulate a list.
    // var list = model.list; // wrong way to manipulate a list. undo/redo doesn't work properly.
    // add item logic here ...
    model.update(list: list);
  }

  void remove(int index) {
    var list = List<String>.from(model.list); // proper way to manipulate a list.
    // var list = model.list; // wrong way to manipulate a list. undo/redo doesn't work properly.
    list.removeAt(index);
    model.update(list: list);
  }

This is how I was able to produce the error. Please read the comments in the code.

@DonnC
Copy link
Author

DonnC commented Feb 5, 2021

Yes the delete function was working perfectly fine and
My model.cart yes its a list, defined in my model as

final List<Cart> cart;

The whole CartController is this

import 'package:momentum/momentum.dart';
import 'package:restaurant_app/models/index.dart';

import 'index.dart';

class CartController extends MomentumController<CartModel> {
  @override
  CartModel init() {
    return CartModel(
      this,
      cart: List<Cart>.empty(growable: true),
    );
  }

  void addToCart(Cart cart) {
    final _cart = model.cart;
    _cart.add(cart);
    model.update(cart: _cart);
  }

  double get totalPrice {
    double _totalPrice = 0.00;

    final _productsInCart = model.cart;

    for (var cartProduct in _productsInCart) {
      _totalPrice += cartProduct.product.price * cartProduct.quantity;
    }

    return _totalPrice;
  }

  void deleteCartProduct(Cart cart) {
    final _cart = model.cart;
    _cart.remove(cart);
    model.update(cart: _cart);
  }

  void undoDelete() {
    this.backward();
  }

  void redoDelete() {
    this.forward();
  }
}

From your suggestions, i wasn't doing it properly, thanks i will try as per your solution and see if i will be able to solve it

@xamantra
Copy link
Owner

xamantra commented Feb 5, 2021

Just now on branch dev-1.3.4. I created a new example module with a basic list (add/delete) and undo/redo function.

  • The component is in: lib/src/components/basic-list-example/
  • The page widget is in: lib/src/widgets/pages/example-basic-list/
Screenrecording_20210206_063940.mp4

@xamantra xamantra changed the title More on Time Travel More on Time Travel (undo/redo) Feb 5, 2021
@DonnC
Copy link
Author

DonnC commented Feb 6, 2021

Thank you so much, this is exactly what im looking for. Will check the example code and refactor my cart controllers too 😃

@DonnC
Copy link
Author

DonnC commented Feb 6, 2021

👌 after i refactored per your suggestion it worked like a charm, but before closing, can you explain more on maxTimeTravelSteps does it correspond to the number of times the model changes or what, for example if i want to delete my cart 3 times and undo, does it mean maxTimeTravelSteps should be 3? or what?

@DonnC DonnC closed this as completed Feb 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants