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

No previous from tap on card on desktop #12671

Merged
merged 8 commits into from
Jan 12, 2018
Merged

No previous from tap on card on desktop #12671

merged 8 commits into from
Jan 12, 2018

Conversation

prateekbh
Copy link
Member

This makes navigation only go forward, when clicked anywhere on card while on desktop.

@@ -286,7 +287,8 @@ class ManualAdvancement extends AdvancementConfig {
((1 - NEXT_SCREEN_AREA_RATIO) * offsetWidth);
const nextScreenAreaMax = offsetLeft + offsetWidth;

if (event.pageX >= nextScreenAreaMin && event.pageX < nextScreenAreaMax) {
if ((event.pageX >= nextScreenAreaMin && event.pageX < nextScreenAreaMax)
Copy link
Member

Choose a reason for hiding this comment

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

Adding knowledge to ManualAdvancement about desktop mode tangles things, IMO.

How about reversing the logic flow? ManualAdvancement could pass along that it comes from an areaClick or something like that, and then AmpStory can reject it.

// ManualAdvancement
if (event.pageX >= nextScreenAreaMin && event.pageX < nextScreenAreaMax) {
   this.onAdvance(/* opt_isFromAreaClick */ true);
}
// AmpStory

buildCallback() {
  //...
  this.advancement_.addAdvanceListener(isFromAreaClick => {
    // TODO(alanorozco): opt_isAutomatic is incorrect in this case, should be passed from
    // advancement class. Ideally refactor into AdvancementType enum (`AUTO/AREA_CLICK/BUTTON_CLICK`).
    this.next(/* opt_isAutomaticAdvance */ !isFromAreaClick, isFromAreaClick));
  });
}

// next() passes arg thru to switchTo_()

// ...
switchTo_(targetPageId, opt_isFromAreaClick) {
   const payload = {targetPageId, isFromAreaClick: !!opt_isFromAreaClick};

  // ...
}

Copy link
Member Author

Choose a reason for hiding this comment

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

@alanorozco I completely agree with this.

However in the above approach i'll still be able to either let it go forward or ignore it.
There would still be a probability that I end up calling previous from ManualAdvancement and in the end call .next from inside it. which would again be ugly.

Can we instead remove onAdvance / onPrevious from AdvancementConfiguration and just have onNavigate? This ways AdvancementConfiguration and its subclasses can pass the type of navigation and its metadata.

e.g. onNavigate({NAVIGATION.MANUAL/TIMER/MEDIA, TAP_AREA: 0.8}) and then AMP-STORY-PAGE can decide whether to call .next or .previous

Copy link
Member

Choose a reason for hiding this comment

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

As discussed offline: Best idea is to add a new NAVIGATION event that specifies direction and both target IDs.

@prateekbh prateekbh changed the title No previous from tap on card on desktop [WIP] No previous from tap on card on desktop Jan 11, 2018
@prateekbh prateekbh changed the title [WIP] No previous from tap on card on desktop No previous from tap on card on desktop Jan 11, 2018
if (pageId === null) {
dispatch(this.element, EventType.SHOW_BOOKEND, /* opt_bubbles */ true);
return;
if (navigationDirection === NAVIGATION_DIRECTION.NEXT) {
Copy link
Member

@alanorozco alanorozco Jan 11, 2018

Choose a reason for hiding this comment

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

The approach can be changed so that concepts aren't as scattered, and won't require you to add a new concept for tap/button/keyboard navigation.

Other bonuses of the proposed approach:

  • Improves readability.
  • Isolates logical concepts.
  • Fewer changes.
  • Paves the way for:
    • Further simplification
    • Fixing the incorrect automatic advance bug (which also allows me to make a change to pass it to analytics! yay!).

Split concepts early on

  1. Advancement.addPreviousListener and Advancement.addNextListener should remain as-is.

  2. Create an additional Advancement.addTapNavigationListener method. This will be defined at the super-class level (AdvancementConfig): add onTapNavigation() method (same implementation as onAdvance() and onPrevious()) and trigger that from maybePerformNavigation_()

  3. Pass a TapNavigationDirection enum to tapNavigationListener callbacks.

Note: TapNavigationDirection must be defined as capitalized camel-case (per our style) and annotated as an enum:

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

Since this leaves the concept of next/previous intact, you can revert the changes made to AmpStory and AmpStoryPage.

Create a new event type that will work as an "adapter".

  1. Dispatch event from the AmpStoryPage level.
onTapNavigation_(direction) { // @param {!TapNavigationDirection} direction
    dispatchCustom(this.win, this.element, EventType.TAP_NAVIGATION, {
      direction,
      previousPageId: this.getPreviousPageId_(),
      nextPageId: this.getNextPageId_(),
    });
}
  1. Let AmpStory convert the event.

This way we contain the special-case for desktop in only one callback!

Note that dispatchNextOrBookend_ and dispatchPreviousOrHint_ trigger on this.element (== <amp-story>).

this.element.addEventListener(EventType.TAP_NAVIGATION, e => {
  const {direction, nextPageId, previousPageId} = e.details;
  if (this.isDesktop_()) {
    // Desktop should always go to next page on page tap.
    this.dispatchNextOrBookend_(nextPageId);
    return;
  }
  if (direction === TapNavigationDirection.NEXT) {
    this.dispatchNextOrBookend_(previousPageId);
    return;
  }
  if (direction === TapNavigationDirection.PREVIOUS) {
    this.dispatchPreviousOrHint_(previousPageId);
    return;
  }
});

* Delegated the navigation decision to AMP-STORY via event.
* @param {number} navigationDirection The direction in which navigation needs to takes place.
*/
navigate(navigationDirection) {
Copy link
Member

Choose a reason for hiding this comment

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

navigateOnTap(direction) {

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

@@ -28,6 +28,11 @@ const NEXT_SCREEN_AREA_RATIO = 0.75;
/** @const {number} */
const POLL_INTERVAL_MS = 250;

/** @const {!Object<string, number>} */
Copy link
Member

Choose a reason for hiding this comment

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

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

@@ -354,6 +354,18 @@ export class AmpStory extends AMP.BaseElement {
this.ampStoryHint_.showFirstPageHintOverlay();
});

this.element.addEventListener(EventType.TAP_NAVIGATION, e => {
const {navigationDirection} = e.detail;
if (navigationDirection === NAVIGATION_DIRECTION.NEXT) {
Copy link
Member

Choose a reason for hiding this comment

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

  1. Remove navigation as a prefix (i.e. direction is fine)
  2. Short-circuit classes for special cases are always better.
if (this.isDesktop_()) {
  this.next_();
  return;
}

if (direction == TapNavigationDirection.PREVIOUS) {
  this.previous_();
} else {
  this.next_():
}

Copy link
Member Author

Choose a reason for hiding this comment

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

just curious why is one better that other?
i know the care where the else is huge block and gets intended, but why otherwise?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, it's more readable as you mentioned. It also makes a clearer change if it ever gets removed in the future.

*/
navigate(navigationDirection) {
// const prevPageId = this.getPreviousPageId_();
// const nextPageId = this.getNextPageId_(/* opt_isAutomaticAdvance */ true);
Copy link
Member

Choose a reason for hiding this comment

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

Remove commented-out code.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

* @param {number} navigationDirection Direction of navigation
* @protected
*/
onNavigate(navigationDirection) {
Copy link
Member

Choose a reason for hiding this comment

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

onTapNavigation

Copy link
Member

Choose a reason for hiding this comment

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

^

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

* Delegated the navigation decision to AMP-STORY via event.
* @param {number} direction The direction in which navigation needs to takes place.
*/
navigate(direction) {
Copy link
Member

Choose a reason for hiding this comment

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

nit: navigateOnTap

Copy link
Member Author

Choose a reason for hiding this comment

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

Done!

* @param {number} navigationDirection Direction of navigation
* @protected
*/
onNavigate(navigationDirection) {
Copy link
Member

Choose a reason for hiding this comment

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

^


if (direction === TapNavigationDirection.NEXT) {
this.next_();
} else {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: can you explicitly check that this is TapNavigationDirection.PREVIOUS?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

@newmuis newmuis merged commit ff974c1 into ampproject:master Jan 12, 2018
@prateekbh prateekbh deleted the noBackOnCardOnDesktop branch January 12, 2018 19:39
gzgogo pushed a commit to gzgogo/amphtml that referenced this pull request Jan 26, 2018
* no back from card tap on desktop

* fixing types

* refactor manual advancement

* changing names

* explicit previous check
RanAbram pushed a commit to RanAbram/amphtml that referenced this pull request Mar 12, 2018
* no back from card tap on desktop

* fixing types

* refactor manual advancement

* changing names

* explicit previous check
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.

4 participants