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
✨Add info dialog containing a link to the canonical URL to embedded stories #15130
Conversation
Will wait for approval, then copy this to 1.0. |
@@ -168,6 +169,7 @@ declareExtension('amp-story', '1.0', { | |||
'amp-story-hint', | |||
'amp-story-unsupported-browser-layer', | |||
'amp-story-viewport-warning-layer', | |||
// TODO(newmuis): 'amp-story-info-dialog', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
forgot to remove this todo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh nvm, I didn't see it was for 1.0.
return Promise.resolve(); | ||
} | ||
|
||
return this.vsync_.runPromise({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: We're trying to move away from vsync, and preferred method is baseElement.measureMutateElement() or using resources
like seen here.
/** @const {string} Class to toggle the info dialog link. */ | ||
export const MOREINFO_VISIBLE_CLASS = 'i-amphtml-story-info-moreinfo-visible'; | ||
|
||
export class InfoDialog { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: add comment stating what this class is / does.
createShadowRootWithStyle(root, this.element_, CSS); | ||
this.initializeListeners_(); | ||
|
||
const appendPromise = this.vsync_.runPromise({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently, we have to use resources
instead of vsync
now. It is going to log warnings/errors soon, we'll have to migrate everything anyways, so it's not a big deal if you don't want to switch here.
|
||
const appendPromise = this.vsync_.runPromise({ | ||
mutate: () => { | ||
this.innerContainerEl_ = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I learned from other team members the other day that since a DOM query doesn't trigger any relayout, we don't have to execute it in a measure callback
But more importantly, it looks like you mixed the mutate/measure keywords
*/ | ||
onInfoClick_() { | ||
const isOpen = this.storeService_.get(StateProperty.INFO_DIALOG_STATE); | ||
this.storeService_.dispatch(Action.TOGGLE_INFO_DIALOG, !isOpen); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super nitty / discussion:
Could we build the domain info dialog only when the user clicks this button to open it? I believe the code would be easy to write, but there may be edge cases I don't know about.
Would calling this.build().then(/* Add class to display the dialog */)
from the store info dialog state listener work?
Opening the dialog becoming asynchronous, we then might want to get this onInfoClick
method a way to open the dialog only, to make sure a user clicking twice on this button doesn't hide the dialog back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it may be slightly more complicated due to the promise for the more info link. Mind if I add in a follow up PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good :)
}); | ||
|
||
it('should build the info dialog', () => { | ||
infoDialog.build().then(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does mocha know it has to wait to run the assertions here and below? Do we have to return the promise?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops 😄
Adding @choumx to review the usage of |
display: none !important; | ||
} | ||
|
||
.i-amphtml-embedded .i-amphtml-story-info-control { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I may be missing something here, but it looks like this wouldn't work because the i-amphtml-embedded
class isn't set in the shadow DOM?
Apparently, all we'd have to do would be to add this class ourselves when building the system layer. Once we retrieve the viewer
through viewerForDoc
, there's this viewer.isEmbedded
method.
Also, I think it'd be great to add this test in the amp-story
file, so we don't even build the component if we don't need to
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
PTAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for implementing all these suggestions :))
this.setHeading_(), | ||
this.setPageLink_(pageUrl), | ||
this.requestMoreInfoLink_() | ||
.then(moreInfoUrl => this.setMoreInfoLinkUrl_(moreInfoUrl)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't know if you want to wait on this promise since it could take a long time if viewer times out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The promise is actually only used for testing; not sure how best to denote that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a comment on the @return
line.
return messagingPromise | ||
.then(() => { | ||
return this.viewer_.sendMessageAwaitResponse('moreInfoLinkUrl', | ||
/* data */ undefined); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the runtime to ask for this URL or can it be provided by the viewer at load time via hash param? See viewer-impl.getParam()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was considered, but decided against to keep the URL length down, since we don't strictly need this populated when the document is initialized (since the user is likely to not click the button that renders this UI until after the messaging has completed).
94ff4b2
to
2751140
Compare
2751140
to
56e180c
Compare
56e180c
to
b890626
Compare
I will migrate this to 1.0 in a separate PR. |
Fixes #14923