Skip to content
This repository has been archived by the owner on Jan 17, 2023. It is now read-only.

Fixes #4848 - Header Without text labels #4940

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions locales/en-US/server.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ gHomeLink = Home
gNoShots
.alt = No shots found
gScreenshotsDescription = Screenshots made simple. Take, save, and share screenshots without leaving Firefox.
gSettings = Settings
gSignIn = Sign In

## Header
buttonSettings =
Expand Down Expand Up @@ -98,7 +96,6 @@ shotPageAlertErrorUpdatingTitle = Error saving title
shotPageConfirmDelete = Are you sure you want to delete this shot permanently?
shotPageShareButton =
.title = Share
shotPageCopy = Copy
shotPageCopyButton =
.title = Copy image to clipboard
shotPageCopied = Copied
Expand Down Expand Up @@ -135,13 +132,6 @@ shotPageBackToHomeButton =
.title = Homepage
shotPageAllShotsButton =
.title = All Shots
shotPageAllShots = All Shots
shotPageDownload = Download
# Note: Draw text is used on shot page as a verb (action)
shotPageDraw = Draw
# Note: Favorite text is used on shot page as a verb (action)
shotPageFavorite = Favorite
shotPageDelete = Delete
shotPageScreenshotsDescription = Screenshots made simple. Take, save, and share screenshots without leaving Firefox.
shotPageDMCAMessage = This shot is no longer available due to a third party intellectual property claim.
# Note: { $dmca } is a placeholder for a link to send email (a 'mailto' link)
Expand Down
9 changes: 3 additions & 6 deletions server/src/delete-shot-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,10 @@ exports.DeleteShotButton = class DeleteShotButton extends React.Component {
}

let deleteButtonStyle = null;
let deleteText = null;
if (this.props.isIcon) {
deleteButtonStyle = `button transparent trash ${deletePanelOpenClass}`;
} else {
deleteButtonStyle = `nav-button transparent icon-trash trash ${deletePanelOpenClass}`;
deleteText = <Localized id="shotPageDelete">
<span>Delete</span>
</Localized>;
deleteButtonStyle = `button nav-button transparent ${deletePanelOpenClass}`;
}

return (
Expand All @@ -93,7 +89,7 @@ exports.DeleteShotButton = class DeleteShotButton extends React.Component {
title="Delete this shot permanently"
onClick={this.onClickDelete.bind(this)}
ref={this.trashButtonRef}>
{ deleteText }
<img src={this.props.staticLink("/static/img/icon-trash.svg")} />
</button>
</Localized>
{ confirmationPanel }
Expand All @@ -107,4 +103,5 @@ exports.DeleteShotButton.propTypes = {
confirmDeleteHandler: PropTypes.func,
cancelDeleteHandler: PropTypes.func,
isIcon: PropTypes.bool,
staticLink: PropTypes.func,
Copy link
Member

Choose a reason for hiding this comment

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

Maybe staticLink should be defined in the base header, instead of being passed around, since it seems to be used in all the headers

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Slightly confused by above comment, by base header you mean inside header.js, am I missing something here?

};
2 changes: 1 addition & 1 deletion server/src/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ exports.Header = function Header(props) {

exports.Header.propTypes = {
hasLogo: PropTypes.bool,
children: PropTypes.node.isRequired,
children: PropTypes.node,
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 addresses server warning in logs when Header doesn't have children

isOwner: PropTypes.bool,
hasFxa: PropTypes.bool,
shouldGetFirefox: PropTypes.bool,
Expand Down
15 changes: 8 additions & 7 deletions server/src/pages/homepage/homepage-header.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@ exports.HomePageHeader = class HomePageHeader extends React.Component {
renderFxASignIn() {
return (
this.props.isFirefox && this.props.isOwner ?
<SignInButton isAuthenticated={this.props.hasFxa} initialPage="" /> : null
<SignInButton isAuthenticated={this.props.hasFxa} initialPage=""
staticLink={this.props.staticLink} /> : null
);
}

render() {
let myShots;
if (this.props.isOwner) {
myShots = <Localized id="shotIndexPageMyShotsButton" attrs={{title: true}}>
<a className="nav-button icon-shots" title="My Shots" href="/shots" onClick={ this.onClickMyShots.bind(this) } tabIndex="0">
<Localized id="gMyShots">
<span>My Shots</span>
</Localized>
</a>
</Localized>;
<a className="nav-button icon-shots" title="My Shots" href="/shots"
onClick={ this.onClickMyShots.bind(this) } tabIndex="0">
<img src={this.props.staticLink("/static/img/icon-shots.svg")} />
Copy link
Member

Choose a reason for hiding this comment

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

Should these images have alt text? I'm not sure

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure either, in share-button we have similar tags where img is embedded inside link and have omitted img alt in favor of title attribute on link. https://github.com/mozilla-services/screenshots/blob/master/server/src/share-buttons.js#L129

Copy link
Member

Choose a reason for hiding this comment

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

Cool, we can leave it for now, and see if it triggers the a11y linter later

Copy link
Collaborator

Choose a reason for hiding this comment

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

We should add alt text to all of our images for a11y.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Filed #4976 to take it up in Q4 with a11y bugs

</a>
</Localized>;
}

const signin = this.renderFxASignIn();
Expand All @@ -49,4 +49,5 @@ exports.HomePageHeader.propTypes = {
hasFxa: PropTypes.bool,
isOwner: PropTypes.bool,
isFirefox: PropTypes.bool,
staticLink: PropTypes.func,
};
3 changes: 2 additions & 1 deletion server/src/pages/homepage/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class Body extends React.Component {
return (
<reactruntime.BodyTemplate {...this.props}>
<HomePageHeader isOwner={this.props.showMyShots} isFirefox={this.props.isFirefox}
hasFxa={this.props.hasFxa} />
hasFxa={this.props.hasFxa} staticLink={this.props.staticLink}/>
<div className="banner">
<div className="banner-image-back" />
<div className="banner-container">
Expand Down Expand Up @@ -168,6 +168,7 @@ Body.propTypes = {
firefoxVersion: PropTypes.string,
isFirefox: PropTypes.bool,
showMyShots: PropTypes.bool,
staticLink: PropTypes.func,
};

exports.HeadFactory = React.createFactory(Head);
Expand Down
4 changes: 2 additions & 2 deletions server/src/pages/shot/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ exports.Editor = class Editor extends React.Component {
const redoButtonState = this.state.canRedo ? "active" : "inactive";

return <div className="editor-header">
<div className="shot-main-actions annotation-main-actions">
<div className="shot-edit-main-actions annotation-main-actions">
<div className="annotation-tools">
<Localized id="annotationCropButton" attrs={{title: true}}>
<button className={`button transparent crop-button`} id="crop" onClick={this.onClickCrop.bind(this)} title="Crop"></button>
Expand Down Expand Up @@ -217,7 +217,7 @@ exports.Editor = class Editor extends React.Component {
</Localized>
</div>
</div>
<div className="shot-alt-actions">
<div className="shot-edit-alt-actions">
<Localized id="annotationSaveEditButton" attrs={{title: true}}>
<button className="button primary save" id="save" onClick={ this.onClickSave.bind(this) } disabled = { this.state.actionsDisabled } title="Save edit">Save</button>
</Localized>
Expand Down
33 changes: 17 additions & 16 deletions server/src/pages/shot/shotpage-header.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ exports.ShotPageHeader = class ShotPageHeader extends React.Component {
return (
<Localized id="shotPageAllShotsButton" attrs={{title: true}}>
<a className="nav-button icon-shots" href="/shots" tabIndex="0" title="All Shots">
<Localized id="shotPageAllShots">
<span>All Shots</span>
</Localized>
<img src={this.props.staticLink("/static/img/icon-shots.svg")} />
</a>
</Localized>
);
Expand All @@ -55,14 +53,14 @@ exports.ShotPageHeader = class ShotPageHeader extends React.Component {
const timeDiff = <TimeDiff date={shot.createdDate} />;
let expirationSubtitle;
if (this.props.expireTime === null) {
expirationSubtitle = <Localized id="shotPageDoesNotExpire"><span>does not expire</span></Localized>;
expirationSubtitle = <Localized id="shotPageDoesNotExpire"><span className="expire-info">does not expire</span></Localized>;
} else {
const expired = this.props.expireTime < Date.now();
const expireTimeDiff = <TimeDiff date={this.props.expireTime}/>;
if (expired) {
expirationSubtitle = <Localized id="shotPageTimeExpired" timediff={expireTimeDiff}><span>expired {expireTimeDiff}</span></Localized>;
expirationSubtitle = <Localized id="shotPageTimeExpired" timediff={expireTimeDiff}><span className="expire-info">expired {expireTimeDiff}</span></Localized>;
} else {
expirationSubtitle = <Localized id="shotPageTimeExpiresIn" timediff={expireTimeDiff}><span>expires {expireTimeDiff}</span></Localized>;
expirationSubtitle = <Localized id="shotPageTimeExpiresIn" timediff={expireTimeDiff}><span className="expire-info">expires {expireTimeDiff}</span></Localized>;
}
}

Expand All @@ -72,7 +70,7 @@ exports.ShotPageHeader = class ShotPageHeader extends React.Component {
<EditableTitle title={shot.title} isOwner={this.props.isOwner} />
<div className="shot-subtitle">
{ linkTextShort ? <a className="subtitle-link" rel="noopener noreferrer" href={ shot.url } target="_blank" onClick={ this.onClickOrigUrl.bind(this, "navbar") }>{ linkTextShort }</a> : null }
<span className="time-diff">{ timeDiff }</span>
<span className="time-diff expire-info">{ timeDiff }</span>
{ expirationSubtitle }
</div>
</div>
Expand All @@ -93,7 +91,8 @@ exports.ShotPageHeader = class ShotPageHeader extends React.Component {
return (
this.props.isOwner ?
<div className="shot-fxa-signin">
<SignInButton isAuthenticated={this.props.isFxaAuthenticated} initialPage={this.props.shot.id} />
<SignInButton isAuthenticated={this.props.isFxaAuthenticated} initialPage={this.props.shot.id}
staticLink={this.props.staticLink} />
</div> : null
);
}
Expand All @@ -105,13 +104,13 @@ exports.ShotPageHeader = class ShotPageHeader extends React.Component {

return (
<Header shouldGetFirefox={this.props.shouldGetFirefox} isOwner={this.props.isOwner}
hasFxa={this.props.isFxaAuthenticated}>
hasFxa={this.props.isFxaAuthenticated}>
{ myShotsText }
{ shotInfo }
<div className="shot-alt-actions">
{ this.props.children }
{ signin }
</div>
{ signin }
</Header>
);
}
Expand All @@ -124,6 +123,7 @@ exports.ShotPageHeader.propTypes = {
isFxaAuthenticated: PropTypes.bool,
expireTime: PropTypes.number,
shouldGetFirefox: PropTypes.bool,
staticLink: PropTypes.func,
};

class EditableTitle extends React.Component {
Expand Down Expand Up @@ -158,12 +158,13 @@ class EditableTitle extends React.Component {

renderEditing() {
return <form onSubmit={this.onExit.bind(this)}>
<input ref={(input) => this.textInput = input}
className="shot-title-input"
style={{minWidth: this.state.minWidth}}
type="text" defaultValue={this.props.title} autoFocus="true"
onBlur={this.onExit.bind(this)} onKeyUp={this.onKeyUp.bind(this)} onFocus={this.onFocus} />
</form>;
<input ref={(input) => this.textInput = input}
className="shot-title-input"
style={{minWidth: this.state.minWidth}}
type="text" defaultValue={this.props.title} autoFocus={true}
onBlur={this.onExit.bind(this)} onKeyUp={this.onKeyUp.bind(this)}
onFocus={this.onFocus} />
</form>;
}

onClick() {
Expand Down
100 changes: 48 additions & 52 deletions server/src/pages/shot/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,68 +363,63 @@ class Body extends React.Component {
let favoriteShotButton = null;
let trashOrFlagButton = null;
let editButton = null;
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 inactive = this.props.isFxaAuthenticated ? "" : "inactive";

favoriteShotButton = <div className="favorite-shot-button">
<Localized id="shotPagefavoriteButton" attrs={{title: true}}>
<button className={`nav-button ${inactive}`}
disabled={!this.props.isFxaAuthenticated}
onClick={this.onClickFavorite.bind(this)}>
<span className={`icon-favorite favorite ${activeFavClass}`} ></span>
<Localized id="shotPageFavorite">
<span className={`favorite-text favorite ${activeFavClass} `}>Favorite</span>
</Localized>
</button></Localized></div>;

const downloadButton = <div className="download-shot-button">
<Localized id="shotPageDownloadShot" attrs={{title: true}}>
<button className="nav-button icon-download" onClick={this.onClickDownload.bind(this)}
title="Download the shot image">
<Localized id="shotPageDownload">
<span>Download</span>
</Localized>
</button>
</Localized></div>;

const copyButton = <div className="copy-img-button" hidden={this.state.isClient && !this.state.canCopy}>
<Localized id="shotPageCopyButton" attrs={{title: true}}>
<button className="nav-button icon-copy transparent copy"
title="Copy image to clipboard"
onClick={this.onClickCopy.bind(this)}>
<Localized id="shotPageCopy">
<span>Copy Image</span>
</Localized>
</button>
</Localized>
</div>;
let downloadButton = null;
let copyButton = null;

if (this.props.isOwner) {
const highlight = this.state.highlightEditButton
? <div className="edit-highlight"
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we should replace this svg highlight with a separate highlighted-pen image (fine to do this in a followup bug)

onClick={this.onClickEdit.bind(this)}
onMouseOver={this.onMouseOverHighlight.bind(this)}
onMouseOut={this.onMouseOutHighlight.bind(this)}>
</div> : null;
const favImgSrc = this.props.expireTime ? this.props.staticLink("/static/img/icon-heart-outline.svg") :
this.props.staticLink("/static/img/icon-heart.svg");
const inactive = this.props.isFxaAuthenticated ? "" : "inactive";

favoriteShotButton = <div className="favorite-shot-button">
<Localized id="shotPagefavoriteButton" attrs={{title: true}}>
<button className={`button transparent nav-button ${inactive}`}
disabled={!this.props.isFxaAuthenticated} onClick={this.onClickFavorite.bind(this)}>
<img src={favImgSrc} />
</button>
</Localized></div>;

trashOrFlagButton = <DeleteShotButton
clickDeleteHandler={ this.clickDeleteHandler.bind(this) }
confirmDeleteHandler={ this.confirmDeleteHandler.bind(this) }
cancelDeleteHandler={ this.cancelDeleteHandler.bind(this) } />;
clickDeleteHandler={this.clickDeleteHandler.bind(this)}
confirmDeleteHandler={this.confirmDeleteHandler.bind(this)}
cancelDeleteHandler={this.cancelDeleteHandler.bind(this)}
staticLink={this.props.staticLink} />;

editButton = this.props.enableAnnotations ? <div className="edit-shot-button">
<Localized id="shotPageEditButton" attrs={{title: true}}>
<button className="nav-button icon-edit transparent edit"
title="Edit this image"
onClick={this.onClickEdit.bind(this)}
ref={(edit) => { this.editButton = edit; }}>
<Localized id="shotPageDraw">
<span>Draw</span>
</Localized>
<button className="button transparent nav-button"
title="Edit this image"
onClick={this.onClickEdit.bind(this)}
ref={(edit) => { this.editButton = edit; }}>
<img src={this.props.staticLink("/static/img/icon-pen.svg")} />
</button>
</Localized>
<PromoDialog promoClose={this.promoClose.bind(this)} display={this.state.promoDialog} />
{ highlight }
</div> : null;

downloadButton = <div className="download-shot-button">
<Localized id="shotPageDownloadShot" attrs={{title: true}}>
<button className={`button transparent nav-button`} onClick={this.onClickDownload.bind(this)}
title="Download the shot image">
<img src={this.props.staticLink("/static/img/icon-download.svg")} />
</button>
</Localized></div>;

copyButton = <div className="copy-img-button" hidden={this.state.isClient && !this.state.canCopy}>
<Localized id="shotPageCopyButton" attrs={{title: true}}>
<button className="button nav-button transparent copy"
title="Copy image to clipboard"
onClick={this.onClickCopy.bind(this)}>
<img src={this.props.staticLink("/static/img/icon-copy.svg")} />
</button>
</Localized></div>;
}

let clip;
Expand All @@ -447,7 +442,8 @@ class Body extends React.Component {
<reactruntime.BodyTemplate {...this.props}>
<div id="frame" className="inverse-color-scheme full-height column-space">
<ShotPageHeader isOwner={this.props.isOwner} isFxaAuthenticated={this.props.isFxaAuthenticated}
shot={this.props.shot} expireTime={this.props.expireTime} shouldGetFirefox={renderGetFirefox}>
shot={this.props.shot} expireTime={this.props.expireTime} shouldGetFirefox={renderGetFirefox}
staticLink={this.props.staticLink}>
{ favoriteShotButton }
{ editButton }
{ copyButton }
Expand Down
5 changes: 4 additions & 1 deletion server/src/pages/shotindex/myshots-header.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ const { Header } = require("../../header.js");

exports.MyShotsHeader = function MyShotsHeader(props) {
const signin = props.enableUserSettings && props.hasDeviceId ?
<SignInButton isAuthenticated={props.hasFxa} initialPage="shots" /> : null;
<SignInButton
isAuthenticated={props.hasFxa} initialPage="shots"
staticLink={props.staticLink} /> : null;

return (
<Header hasLogo={true} isOwner={props.hasDeviceId} hasFxa={props.hasFxa}>
Expand All @@ -20,4 +22,5 @@ exports.MyShotsHeader.propTypes = {
hasFxa: PropTypes.bool,
hasDeviceId: PropTypes.bool,
enableUserSettings: PropTypes.bool,
staticLink: PropTypes.func,
};
Loading