-
Notifications
You must be signed in to change notification settings - Fork 128
Fixes #4685 - [FxA] Common Header Component #4821
Conversation
c94ce9c
to
6f7e129
Compare
6f7e129
to
4a7f276
Compare
Updated PR with common header for homepage and My Shots. Looking into complexity of bringing in shots header into common component |
4a7f276
to
5008428
Compare
server/src/header.js
Outdated
if (!this.props.initiatePage) { | ||
return ( | ||
this.props.isFirefox && this.props.hasDeviceId ? | ||
<SignInButton isAuthenticated={this.props.hasFxa} initiatePage={this.props.initiatePage} /> : null |
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.
To parrot what was mentioned during the synchronous review: initiatePage
is not necessary if we always redirect back to the same page. (If we want to keep it as an option to redirect to a different page post-auth, then please rename it to initialPage
as "initiate" denotes whether to take some action.)
server/src/delete-shot-button.js
Outdated
<Localized id="gDelete"> | ||
<span>Delete</span> | ||
</Localized> | ||
</button> |
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 markup is unnecessarily complicated. A background can be set on the button. Also note that background images are not displayed in high contrast mode. One could argue that the image here is decorative since the button has a text label. But generally speaking, inline images are better for accessibility.
server/src/header.js
Outdated
} | ||
|
||
const signin = this.renderFxASignIn(); | ||
const search = this.props.searchForm && this.props.initiatePage === "shots" ? this.props.searchForm : null; |
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.
Just want to +1 on Jared's concern regarding how and where the content of the header is inserted. We're already special casing for My Shots here; it doesn't feel right.
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 agree it does seem a bit off to have searchForm moved to Header component when rest of its styles and event handlers are in shotIndex view. Will update to move SearchForm rendering outside of Header component
server/src/pages/homepage/view.js
Outdated
{ this.renderGetFirefox() } | ||
</div> | ||
<div className="banner-image-front" /> | ||
<Header hasDeviceId={this.props.showMyShots} isFirefox={this.props.isFirefox} hasFxa={this.props.hasFxa} initiatePage="" /> |
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.
nit: why not just hasDeviceId
or showMyShots
all the way down?
server/src/pages/shot/view.js
Outdated
@@ -346,13 +346,15 @@ class Body extends React.Component { | |||
let editButton; | |||
const highlight = this.state.highlightEditButton ? <div className="edit-highlight" onClick={ this.onClickEdit.bind(this) } onMouseOver={ this.onMouseOverHighlight.bind(this) } onMouseOut={ this.onMouseOutHighlight.bind(this) }></div> : null; | |||
|
|||
const activeFavClass = this.props.expireTime ? "" : "is-fav"; | |||
const activeFavClass = this.props.expireTime ? "un-fav" : "is-fav"; |
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.
un-fav
only affects the span and is-fav
only affects the div. It's confusing when class names are unnecessarily added to elements. Why not have the styles of un-fav
be the default and then is-fav
to toggle? Then we don't even need to change this line.
server/src/pages/shot/view.js
Outdated
</div> | ||
{ favoriteShotButton } | ||
{ trashOrFlagButton } | ||
{ this.props.enableAnnotations ? editButton : null } |
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.
Perhaps move this check up to the assignment of editButton
.
server/src/pages/shot/view.js
Outdated
<Localized id="gMyShots"> | ||
<span>My Shots</span> | ||
</Localized> | ||
</button>; |
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 can go in an else
of the if
below.
Just to capture what we discussed in IRC: Seems like the Header is currently doing a lot. It renders header-related stuff for all of the pages, and also contains page-specific code to decide which parts to render. One way to simplify things might be to separate a generic Header, that renders any sub-components (passed as props) into a region in the DOM, from page-specific headers that know how to create and render page-specific components into the generic Header. For instance, a ShotPageHeader might render itself by creating components for the shot info and shot page buttons, then passing all those components into the Header, actually returning the Header. Any components/UI found on multiple pages, like the blue upsell bar, or the login/settings button, could either be part of the generic Header, or be sub-components on their own. UI that only occurs on a single page (like the favorite button) could just be elements created in the specific page's PageHeader, or you could go further and make each control its own component (might be a lot of work for a first pass, though). I'm not sure this is the best way to break up the complexity, but I think it's one way that could work. There are some nice examples of composing a generic Dialog class with specific Dialog subtypes in the React docs. Happy to chat further, here or on IRC/Slack 👍 |
5008428
to
8e42064
Compare
@chenba @6a68 Thanks for feedback. Updated PR with review comments and below items are in progress
|
@punamdahiya CI failure is caused by linting errors. |
server/src/header.js
Outdated
} | ||
|
||
renderFxASignIn() { | ||
if (!this.props.initialPage) { |
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.
It's unclear this is checking for not the homepage or this.props.initialPage
is 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.
It's checking for both and in either case signIn button on auth redirection will redirect back to homepage which I believe should be ok
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.
With specific headers, this check is no more needed
a103eb1
to
92803dc
Compare
With all the auth related info being passed as props in multiple places, I think this patch is a good candidate for React's Context. |
b8f7d1b
to
fbcc30d
Compare
sendEvent("goto-homepage", "navbar", {useBeacon: true}); | ||
location.href = "/"; | ||
} | ||
// Note: we allow the default action to continue |
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 comment does not make sense as there is no default action.
server/src/pages/shot/view.js
Outdated
|
||
favoriteShotButton = <Localized id="shotPageFavoriteButton"> | ||
<button className={`nav-button ${shouldShow} `} onClick={this.onClickFavorite.bind(this)}> | ||
<div className={`icon-favorite favorite ${activeFavClass}`} ></div> |
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.
Is it not possible to achieve the style we want by wrapping the button in the div, not vice-versa?
</Header> | ||
); | ||
} | ||
}; |
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 component can be a stateless component as well.
server/src/signin-button.js
Outdated
@@ -18,30 +18,35 @@ exports.SignInButton = class SignInButton extends React.Component { | |||
render() { | |||
if (this.state.displaySettings) { | |||
return <Localized id="settingsButton"> | |||
<a className="settings-button" href="/settings" aria-label="Settings"> | |||
<button className="nav-button icon-settings" tabIndex="0" title="Settings" onClick={this.clickHandler.bind(this)}> |
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 should remain a link; it's navigation.
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.
Updated to button for its advantages around built-in keyboard accessibility that lets tab between and activate using Return/Enter
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.
Using links navigate the web is fundamental and I don't agree we should do something else. Also, I can tab among links and navigate by pressing Enter. Is that not the case on macOS Firefox?
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.
It works once we provide href, will update to use navigate link. Thanks
server/src/signin-button.js
Outdated
<span>Sign In</span> | ||
</Localized> | ||
</button> | ||
</Localized>; |
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.
It should be a link here as well.
static/css/partials/_header.scss
Outdated
|
||
display: flex; | ||
height: 96px; | ||
background-color: #f9f9fa; |
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.
$light-default
can be used here instead of the hex value.
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.
Would like some markup and component changes.
f0e86f3
to
5f87669
Compare
Created #4877 to take this refactoring as separate PR |
5f87669
to
ab5df98
Compare
@chenba Updated PR with feedback on markup and using stateless components. Thanks! |
3f2df79
to
d3ff886
Compare
server/src/header.js
Outdated
|
||
exports.Header.propTypes = { | ||
hasLogo: PropTypes.bool, | ||
children: PropTypes.node.isRequired |
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.
Now that #4822 is a thing, this line needs a comma.
|
||
onClickMyShots() { | ||
sendEvent("goto-myshots", "homepage", {useBeacon: true}); | ||
window.location = "/shots"; |
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.
Please use a link for navigation.
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.
+1, updated and rebased
exports.HomePageHeader.propTypes = { | ||
hasFxa: PropTypes.bool, | ||
isOwner: PropTypes.bool, | ||
isFirefox: PropTypes.bool |
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.
Need dangling comma here.
d3ff886
to
545d921
Compare
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.
LGTM. But needs a rebase.
545d921
to
62d1fe9
Compare
@flodolo Can you please review localization changes in the PR. Thanks! |
locales/en-US/server.ftl
Outdated
@@ -11,10 +11,13 @@ gSettings = Settings | |||
gSignIn = Sign In | |||
|
|||
## Header | |||
signInButton = | |||
.aria-label = Sign In | |||
settingsButton = |
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.
If you change attributes in an existing string, you need to change the ID of the string.
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
locales/en-US/server.ftl
Outdated
@@ -123,9 +126,17 @@ shotPageDownloadShot = | |||
.title = Download | |||
shotPageEditButton = | |||
.title = Edit this image | |||
shotPagefavoriteButton = | |||
shotPageFavoriteButton = |
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 would require localizers to retranslate the string. If it's just for cosmetic reasons, I would avoid changing the ID.
locales/en-US/server.ftl
Outdated
shotPageDownload = Download | ||
shotPageDraw = Draw |
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.
Is this a verb or a noun? I assume a verb (action), but please add a comment.
locales/en-US/server.ftl
Outdated
shotPageDownload = Download | ||
shotPageDraw = Draw | ||
shotPageFavorite = Favorite |
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.
Same question: verb or noun?
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.
It's a verb, added comment to highlight that
62d1fe9
to
914c800
Compare
@flodolo Thanks for review, updated PR with suggested changes |
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.
It would be really helpful to keep sequential commits when doing fixes, and only squash (if needed) before merge. Without that, there's no easy way to tell what changed between the two commits.
locales/en-US/server.ftl
Outdated
shotPageDownload = Download | ||
# Note: Draw, Favorite and Delete text below is used on shot page header buttons as a verb (action) |
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.
Please use one comment per string (not really needed for 'delete', since there's no space for confusion). Localizers don't see the file, see one string at a time, and the associated comment.
The alternative is to use section comments, but I'd avoid that in this case.
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.
@flodolo Good to know, Done. Thanks!
No description provided.