Skip to content

Conversation

bramanudom
Copy link
Contributor

#20083

Ideally when a user navigates back within a story, they go back to the page they came from.

For example, if a user is on page 4, then navigates to page 5, then goes back, they should go back to page 4. With branching, this still needs to be the case. That is, if a user is on page 1, then jumps to page 5, then goes back, they should go back to page 1.

This PR adds a story level stack that keeps track of the user's path while navigating through the story.

@bramanudom
Copy link
Contributor Author

Note that the current unit test "should navigate back to the correct previous page after advance-to" is expected to fail until #20116 successfully merges.

updateStoryPath_(targetPageId, direction) {
const targetPage = this.getPageById(targetPageId);
if (direction == 'previous') {
this.storyPath_.pop();
Copy link
Contributor

Choose a reason for hiding this comment

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

curious: have you tried navigating to a page in the story, navigating outside of the story, clicking back in the browser history to re-enter the story, and then navigating to the previous page? Will that still work?

Copy link
Contributor

Choose a reason for hiding this comment

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

+1, we might want to store the storyPath_ in the browser history in a following PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for bringing this case to attention, @Enriqe . You're right, the expected previous navigation is broken when the user navigates out of and comes back to the story.

I will send a follow-up PR that updates the browser history like @gmajoulet suggested here and offline.

/**
* Switches to a particular page.
* @param {string} targetPageId
* @param {string} direction
Copy link
Contributor

Choose a reason for hiding this comment

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

If the direction will only ever be a limited set of options, consider using a Closure Compiler @enum type instead of a raw string.

/** @const @enum */
export const TapNavigationDirection = {
'NEXT': 1,
'PREVIOUS': 2,
};

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, in the amp-story-page level.

const {args} = invocation;
if (args) {
this.switchTo_(args['id']);
this.switchTo_(args['id'], 'next');
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we have an enum to store these previous and next values? This way, we'd get compilation errors instead of silent errors if we have a typo :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

this.adPages_ = [];

/** @private @const {!Array<!./amp-story-page.AmpStoryPage>} */
this.storyPath_ = [];
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: maybe storyNavigationPath? In this ever growing file, it's useful to give as much context as possible...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

* @param {string} targetPageId
* @param {string} direction
* @return {!Promise}
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: not your doing, but could you please add a @private here? Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

const oldPage = this.activePage_;
this.activePage_ = targetPage;


Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: no extra new line

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

*/
updateStoryPath_(targetPageId, direction) {
const targetPage = this.getPageById(targetPageId);
if (direction == 'previous') {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: please use strict equality checks, here and below

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

* to the path a user takes.
* @param {string} targetPageId
* @param {string} direction
* @private
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: @return {!AmpStoryPage}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

updateStoryPath_(targetPageId, direction) {
const targetPage = this.getPageById(targetPageId);
if (direction == 'previous') {
this.storyPath_.pop();
Copy link
Contributor

Choose a reason for hiding this comment

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

+1, we might want to store the storyPath_ in the browser history in a following PR.


it('should navigate back to the correct previous page after goToPage',
() => {
toggleExperiment(win, 'amp-story-branching', true);
Copy link
Contributor

Choose a reason for hiding this comment

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

You can enable this experiment for all your describe block, by adding before(() => {/* enable experiment */}) and after(() => {/* Disable experiment */})

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

new MouseEvent('click', {clientX: 0}));
expect(story.activePage_.element.id).to.equal('cover');

toggleExperiment(win, 'amp-story-branching', false);
Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally, a test would only assert one thing, like moving forwards, or moving backwards. Could you please split this test in two tests? It's going to create duplicated code, but in the context of tests it'd actually help debugging, as you'd know right away if you broke forward or backward navigation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This makes sense. I went ahead and removed the expects confirms the correct forwards movement. The advance-to PR itself should already have a test that tests this.

.element.setAttribute('advance-to', 'page-3');

expect(story.activePage_.element.id).to.equal('cover');
// Move forwards
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: formatting // Moves forwards.

Copy link
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
Contributor

@gmajoulet gmajoulet left a comment

Choose a reason for hiding this comment

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

Great!!


/**
* @param {string} targetPageId
* @param {NavigationDirection} direction
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: {!NavigationDirection}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

/**
* Switches to a particular page.
* @param {string} targetPageId
* @param {string} direction
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: {!NavigationDirection}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

describe('amp-story branching', () => {

beforeEach(() => {toggleExperiment(win, 'amp-story-branching', true);});
afterEach(() => {toggleExperiment(win, 'amp-story-branching', false);});
Copy link
Contributor

Choose a reason for hiding this comment

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

Here you could use either before/afterEach() or before/after(). The first one is going to be executed before/after each test, when the first one is going to be executed only once before all the tests, and then once after all the tests. I think we might want the latter in this very use case :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Synced offline, but the tests always fail when using before/after, reproduce-ably. Seems to be a bug!

@bramanudom
Copy link
Contributor Author

bramanudom commented Jan 9, 2019

I think this is ready for merging! 🌴 (for branching) @gmajoulet

@gmajoulet gmajoulet merged commit 7c16757 into ampproject:master Jan 9, 2019
noranazmy pushed a commit to noranazmy/amphtml that referenced this pull request Mar 22, 2019
* added story level stack

* wip: added logic for pushing/ popping

* cleaned up code

* added tests

* added experiment check

* remove console.log

* fixed type error

* addressed PR comments

* addressed PR comments
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