Skip to content

Commit

Permalink
[amp-story-player] ✨♻️ Rewind API (#32931)
Browse files Browse the repository at this point in the history
* rewind API and small refactor

* add private

* simplify to only current story

* use signal_end instead

* revert refactoring

* delete test

* save change for followup

* cleanups

* add test
  • Loading branch information
Enriqe committed Feb 26, 2021
1 parent e340dad commit d14bdcd
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 11 deletions.
1 change: 1 addition & 0 deletions extensions/amp-story/1.0/amp-story.js
Expand Up @@ -839,6 +839,7 @@ export class AmpStory extends AMP.BaseElement {
// there is a way to navigate to pages that does not involve using private
// amp-story methods.
this.viewer_.onMessage('selectPage', (data) => this.onSelectPage_(data));
this.viewer_.onMessage('rewind', () => this.replay_());

if (this.viewerMessagingHandler_) {
this.viewerMessagingHandler_.startListening();
Expand Down
47 changes: 36 additions & 11 deletions src/amp-story-player/amp-story-player-impl.js
Expand Up @@ -257,6 +257,7 @@ export class AmpStoryPlayer {
this.element_.mute = this.mute.bind(this);
this.element_.unmute = this.unmute.bind(this);
this.element_.getStoryState = this.getStoryState.bind(this);
this.element_.rewind = this.rewind.bind(this);
}

/**
Expand Down Expand Up @@ -739,19 +740,11 @@ export class AmpStoryPlayer {
* @return {!Promise}
*/
show(storyUrl, pageId = null) {
// TODO(enriqe): sanitize URLs for matching.
const storyIdx = storyUrl
? findIndex(this.stories_, ({href}) => href === storyUrl)
: this.currentIdx_;

// TODO(#28987): replace for add() once implemented.
if (!this.stories_[storyIdx]) {
throw new Error(`Story URL not found in the player: ${storyUrl}`);
}
const story = this.getStoryFromUrl_(storyUrl);

let renderPromise = Promise.resolve();
if (storyIdx !== this.currentIdx_) {
this.currentIdx_ = storyIdx;
if (story.idx !== this.currentIdx_) {
this.currentIdx_ = story.idx;

renderPromise = this.render_();
this.onNavigation_();
Expand Down Expand Up @@ -1275,6 +1268,38 @@ export class AmpStoryPlayer {
);
}

/**
* Returns the story given a URL.
* @param {string} storyUrl
* @return {!StoryDef}
* @private
*/
getStoryFromUrl_(storyUrl) {
// TODO(enriqe): sanitize URLs for matching.
const storyIdx = storyUrl
? findIndex(this.stories_, ({href}) => href === storyUrl)
: this.currentIdx_;

const story = this.stories_[storyIdx];
if (!story) {
throw new Error(`Story URL not found in the player: ${storyUrl}`);
}

return this.stories_[storyIdx];
}

/**
* Rewinds the given story.
* @param {string} storyUrl
*/
rewind(storyUrl) {
const story = this.getStoryFromUrl_(storyUrl);

story.messagingPromise.then((messaging) =>
messaging.sendRequest('rewind', {})
);
}

/**
* Sends a message to the current story to navigate delta pages.
* @param {number} delta
Expand Down
32 changes: 32 additions & 0 deletions test/unit/test-amp-story-player.js
Expand Up @@ -799,6 +799,38 @@ describes.realWin('AmpStoryPlayer', {amp: false}, (env) => {
);
});

it('rewind() callback should rewind current story', async () => {
const playerEl = win.document.createElement('amp-story-player');
attachPlayerWithStories(playerEl, 1);

const player = new AmpStoryPlayer(win, playerEl);

await player.load();
await nextTick();

const sendRequestSpy = env.sandbox.spy(fakeMessaging, 'sendRequest');
player.rewind('https://example.com/story0.html');
await nextTick();

expect(sendRequestSpy).to.have.been.calledWith('rewind', {});
});

it('rewind() throws when invalid url is provided', async () => {
const playerEl = win.document.createElement('amp-story-player');
attachPlayerWithStories(playerEl, 1);

const player = new AmpStoryPlayer(win, playerEl);

await player.load();
await nextTick();

return expect(() =>
player.rewind('https://example.com/story6.html')
).to.throw(
'Story URL not found in the player: https://example.com/story6.html'
);
});

// TODO(proyectoramirez): delete once add() is implemented.
it('show callback should throw when story is not found', async () => {
const playerEl = win.document.createElement('amp-story-player');
Expand Down

0 comments on commit d14bdcd

Please sign in to comment.