Skip to content

Add goToSlide to scrollable-slides#14477

Merged
cathyxz merged 7 commits intoampproject:masterfrom
cathyxz:feature/carousel-go-to-slide
Apr 10, 2018
Merged

Add goToSlide to scrollable-slides#14477
cathyxz merged 7 commits intoampproject:masterfrom
cathyxz:feature/carousel-go-to-slide

Conversation

@cathyxz
Copy link
Copy Markdown
Contributor

@cathyxz cathyxz commented Apr 6, 2018

Closes #13011.
My only question here is does it make sense to scroll so that the target slide is in the center of the carousel or the left? The way I interpreted the aesthetic of the scrollable-carousel, was that the target slide was the left-most slide. But maybe I'm misinterpreting how people use them.

* Calculates the target scroll position for the given slide index.
* @param {number} index
*/
getPosForSlideIndex_(index) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now this implementation tries to center the target slide. If we remove the latest commit, it will try to left-align the target slide.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think center makes sense. we can revisit if there is interest in other docking locations.

@cathyxz cathyxz force-pushed the feature/carousel-go-to-slide branch from 65e44fa to 03a8466 Compare April 6, 2018 23:36

/**
* Scrolls to the slide at the given slide index.
* @param {*} value
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I would move the parseInt into the registerAction callback, that way this function can declare explicitly that it needs a number.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

this.registerAction('goToSlide', invocation => {
const args = invocation.args;
if (args) {
this.goToSlide_(args['index']);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think this action should be chainable? Actions can return a Promise, and other subsequent actions can be made to wait for that Promise to resolve. I can see a publisher wanting to go to a slide, then do something after the carousel has finished animating to that slide. wdyt?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent idea.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tbh, I am not a big fan of our Promise-based actions since author is not in control of whether they want to chain or parallelize the actions. slidescroll version has a slideChange event. I suggest supporting that event here as well (if not supported already, not sure if it is already coded in the base class or not). With that event, authors can react after a slidechage is fully done.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Okay. =)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So with regards to supporting the slideChange event, in the case where the user is manually scrolling, it's not actually obvious which slide index the carousel is on. Per offline discussion, I'll trigger this event when the action is called, and leave an issue to define slide index in context of scrolling.

Copy link
Copy Markdown
Contributor Author

@cathyxz cathyxz Apr 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, per doc, we shouldn't trigger the event when the action is called:

Fired when the user manually changes the carousel's current slide. Does not fire on autoplay or the goToSlide action.

I'll file an issue for later.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation might be wrong, based on the code, I see it get fired with gotToSlide action.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed: #14505 to avoid getting too greedy. Stacked the PR though.

@cvializ
Copy link
Copy Markdown
Contributor

cvializ commented Apr 9, 2018

For the center vs left question, @aghassemi might have better context than I do, but I think center makes sense. It's an easy change if someone opens a bug.

* Calculates the target scroll position for the given slide index.
* @param {number} index
*/
getPosForSlideIndex_(index) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think center makes sense. we can revisit if there is interest in other docking locations.

* @private
*/
goToSlide_(value) {
const index = parseInt(value, 10);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whole function should become a measure/mutate, where getPosForSlideIndex_ is called in the measure block and start of animation is in the mutate block.

const index = parseInt(args['index'], 10);
this.goToSlide_(index);
}
}, ActionTrust.HIGH);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is high trust needed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I followed the precedence in slidescroll.js here in terms of ActionTrust. I'm not sure why this is high trust, but I imagine that the trust level should be consistent across the two carousel implementations.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both can become low trust given the UI changes are fully contained within the container.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I think the reason this is high trust is because we allow amp-bind for the [slide] attribute, which also must update when change the slide (no matter how). I reverted the trust change on type="slides". We can keep it low trust on type="carousel" until we implement the slideChange event and other support for amp-bind.

});
};

this.vsync_.run({
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VSync will be a deprecated API soon (I'm actively removing every use). Please use BaseElement#measureMutateElement, and note that state is not supported (it doesn't help you in the this situation anyways).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's good to know! Could we get a wider distribution on this? I think the currently known best practice is still to use vsync for measurements and mutations.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added to tomorrow's deep dive.

* @param {number} index
* @private
*/
goToSlide_(index) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be used anywhere else?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope.

mutate: mutateSlidePosition,
}, {});
this.measureElement(() => this.getPosForSlideIndex_(index))
.then(newPos => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: measure.then.mutate is to take two vsync cycles (~16ms-32ms lag) to complete. You can combine them into a single #measureMutateElement call, which will complete in 1 cycle.

Copy link
Copy Markdown
Contributor Author

@cathyxz cathyxz Apr 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will that guarantee that the measure finishes before the mutate? Implemented the change assuming that the above is true.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

@cathyxz cathyxz force-pushed the feature/carousel-go-to-slide branch from 158c1dc to 27cf19c Compare April 9, 2018 22:59
@cathyxz
Copy link
Copy Markdown
Contributor Author

cathyxz commented Apr 9, 2018

@jridgewell PTAL?

Copy link
Copy Markdown
Contributor

@jridgewell jridgewell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defer to Ali.

@cathyxz
Copy link
Copy Markdown
Contributor Author

cathyxz commented Apr 10, 2018

The failing test seems legitimate. Investigating.

@aghassemi
Copy link
Copy Markdown
Contributor

@cathyxz In the previous commit, trust level of the slidechange "event" was changed to low. We want to keep the events high trust, just lower the goToSlide "action" on slidescroll to low trust.

@aghassemi
Copy link
Copy Markdown
Contributor

LGTM

@cathyxz cathyxz merged commit db29e31 into ampproject:master Apr 10, 2018
@cathyxz cathyxz deleted the feature/carousel-go-to-slide branch April 10, 2018 18:58
This was referenced Apr 16, 2018
glevitzky pushed a commit that referenced this pull request Apr 27, 2018
* Add goToSlide to scrollable-slides

* Try to center the target slide

* Wrap everything in vsync

* Remove vsync, set action trust to LOW

* Use measureMutateElement for shorter cycle

* Revert ActionTrust change on slidescroll

* Change goToSlide action to low trust
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants