diff --git a/package.json b/package.json index a97713d44790787795d671f30d6f5d9a384ac8ae..0d9ed6b57e38dc448a3da828e3acb5cc24a33035 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "classnames": "^2.2.5", "detect-browser": "^2.1.0", "event-target-shim": "^3.0.1", + "form-urlencoded": "^2.0.4", "jsonschema": "^1.2.2", "minijanus": "^0.5.0", "mobile-detect": "^1.4.1", diff --git a/src/assets/stylesheets/index.scss b/src/assets/stylesheets/index.scss index 19cf66f85dad36b7b81c9ada28a272a755a5b9e9..38833657208e9a58a19ef8b10add9e8a5ceaa25d 100644 --- a/src/assets/stylesheets/index.scss +++ b/src/assets/stylesheets/index.scss @@ -233,10 +233,47 @@ body { z-index: 2; } +.mailing-list-form { + display: flex; + height: 100%; + flex-direction: column; + justify-content: center; + text-align: center; + margin: 0; + + &__first { + width: 100%; + } + + &__email_field { + @extend %rounded-border; + @extend %default-font; + color: $light-text; + font-size: 1.2em; + background-color: transparent; + line-height: 2.0em; + padding-left: 1.25em; + padding-right: 1.25em; + margin: 0.5em 0; + width: 100%; + } + + &__submit { + @extend %bottom-button; + border: 0; + margin-top: 16px; + } + + &__privacy { + margin-top: 10px; + font-size: 0.7em; + } +} + .dialog { display: grid; grid-template-columns: 1fr 20px minmax(200px,500px) 20px 1fr; - grid-template-rows: 1fr 20px 320px 20px 1fr; + grid-template-rows: 1fr 20px 275px 20px 1fr; width: 100%; height: 100%; background-color: rgba(0,0,0,.6); @@ -255,7 +292,9 @@ body { display: flex; flex-direction: column; align-items: center; - justify-content: flex-start; + justify-content: center; + text-align: center; + position: relative; &__title { @extend %top-title; @@ -267,25 +306,22 @@ body { font-size: 1.1em; margin-top: 20px; color: $grey-text; + display: flex; + flex-direction: column; a { color: white } } - &__button-container { - flex: 10; - display: flex; - justify-content: center; - align-items: center; + &__close { + position: absolute; + left: 12px; + top: 6px; + color: white; + font-size: 1.4em; + + background: none; cursor: pointer; - width: 111px; - height: 111px; - - &__button { - @extend %bottom-button; - background: none; - cursor: pointer; - border: none; - } + border: none; } } } diff --git a/src/assets/translations.data.json b/src/assets/translations.data.json index f42de20e47744ccc09b05bec6a484244c56f27be..a171d6f416bf35804882c1e567815cffedb51367 100644 --- a/src/assets/translations.data.json +++ b/src/assets/translations.data.json @@ -45,13 +45,15 @@ "home.webvr_disclaimer_post": " experiment by ", "home.webvr_disclaimer_mr_team": "Mozilla Mixed Reality", "home.view_source": "View Source", - "home.join_on_slack": "Join us on Slack", + "home.join_us": "Join the Conversation", "home.report_issue": "Report an Issue", "home.get_updates": "Get Updates", "home.hero_title": "A new way to get together online.", "home.hero_subtitle": "Laugh, play, get stuff done, or just hang out.", "home.made_with_love": "made with 🦆 by ", "home.environment_author_by": " by ", - "home.dialog.close": "CLOSE" + "home.dialog.close": "CLOSE", + "mailing_list.privacy_label": "I'm okay with Mozilla handling my info as explained in", + "mailing_list.privacy_link": "this Privacy Notice" } } diff --git a/src/react-components/home-root.js b/src/react-components/home-root.js index 334f3d3b49913636b4e3624d6f99c3754694888e..d91dfdbed6e726a785cbb8744d35e3dab066085c 100644 --- a/src/react-components/home-root.js +++ b/src/react-components/home-root.js @@ -4,6 +4,7 @@ import { IntlProvider, FormattedMessage, addLocaleData } from "react-intl"; import en from "react-intl/locale-data/en"; import homeVideo from "../assets/video/home.webm"; import classNames from "classnames"; +import formurlencoded from "form-urlencoded"; import HubCreatePanel from "./hub-create-panel.js"; @@ -30,7 +31,9 @@ class HomeRoot extends Component { state = { environments: [], - dialogType: null + dialogType: null, + mailingListEmail: "", + mailingListPrivacy: false }; componentDidMount() { @@ -41,8 +44,8 @@ class HomeRoot extends Component { showDialog = dialogType => { return e => { e.preventDefault(); + e.stopPropagation(); this.setState({ dialogType }); - return false; }; }; @@ -50,6 +53,28 @@ class HomeRoot extends Component { this.setState({ dialogType: null }); }; + signUpForMailingList = async e => { + e.preventDefault(); + e.stopPropagation(); + if (!this.state.mailingListPrivacy) return; + + const url = "https://www.mozilla.org/en-US/newsletter/"; + + const payload = { + email: this.state.mailingListEmail, + newsletters: "mixed-reality", + privacy: true, + fmt: "H", + source_url: document.location.href + }; + + await fetch(url, { + body: formurlencoded(payload), + method: "POST", + headers: { "content-type": "application/x-www-form-urlencoded" } + }).then(() => this.setState({ dialogType: "email_submitted" })); + }; + loadEnvironments = () => { const environments = []; @@ -72,38 +97,62 @@ class HomeRoot extends Component { switch (this.state.dialogType) { // TODO i18n, FormattedMessage doesn't play nicely with links case "slack": - dialogTitle = "Join us on Slack"; + dialogTitle = "Get in Touch"; dialogBody = ( <span> Want to join the conversation? <p /> Join us on the{" "} - <a href="http://webvr-slack.herokuapp.com/" target="_blank" rel="noopener noreferrer"> + <a href="https://webvr-slack.herokuapp.com/" target="_blank" rel="noopener noreferrer"> WebVR Slack </a>{" "} - in the #social channel. + in the #social channel.<br />VR meetups every Friday at noon PST! + <p /> Or, tweet at{" "} + <a href="https://twitter.com/mozillareality" target="_blank" rel="noopener noreferrer"> + @mozillareality + </a>{" "} + on Twitter. </span> ); break; + case "email_submitted": + dialogTitle = ""; + dialogBody = "Great! Please check your e-mail to confirm your subscription."; + break; case "updates": - dialogTitle = "Get Updates"; + dialogTitle = ""; dialogBody = ( <span> - We're adding more features to Hubs every week. - <p /> - To receive regular release notes, join our{" "} - <a href="#" target="_blank"> - mailing list - </a>. + Sign up to get release notes about new features. <p /> - You can also follow us on Twitter{" "} - <a href="https://twitter.com/mozillareality" target="_blank" rel="noopener noreferrer"> - @mozillareality - </a>{" "} - or on the{" "} - <a href="https://blog.mozvr.com/" target="_blank" rel="noopener noreferrer"> - Mozilla Mixed Reality Blog - </a>. + <form onSubmit={this.signUpForMailingList}> + <div className="mailing-list-form"> + <input + type="email" + value={this.state.mailingListEmail} + onChange={e => this.setState({ mailingListEmail: e.target.value })} + className="mailing-list-form__email_field" + required + placeholder="Your email here" + /> + <label className="mailing-list-form__privacy"> + <input + className="mailing-list-form__privacy_checkbox" + type="checkbox" + required + value={this.state.mailingListPrivacy} + onChange={e => this.setState({ mailingListPrivacy: e.target.checked })} + /> + <span className="mailing-list-form__privacy_label"> + <FormattedMessage id="mailing_list.privacy_label" />{" "} + <a target="_blank" rel="noopener noreferrer" href="https://www.mozilla.org/en-US/privacy/"> + <FormattedMessage id="mailing_list.privacy_link" /> + </a> + </span> + </label> + <input className="mailing-list-form__submit" type="submit" value="Sign Up Now" /> + </div> + </form> </span> ); break; @@ -194,7 +243,7 @@ class HomeRoot extends Component { href="#" onClick={this.showDialog("slack")} > - <FormattedMessage id="home.join_on_slack" /> + <FormattedMessage id="home.join_us" /> </a> <a className="footer-content__links__link" @@ -223,20 +272,17 @@ class HomeRoot extends Component { <video playsInline autoPlay muted loop className="background-video" id="background-video"> <source src={homeVideo} type="video/webm" /> </video> - {dialogTitle && ( + {this.state.dialogType && ( <div className="overlay"> <div className="dialog"> <div className="dialog__box"> <div className="dialog__box__contents"> + <button className="dialog__box__contents__close" onClick={this.closeDialog}> + <span>🗙</span> + </button> <div className="dialog__box__contents__title">{dialogTitle}</div> <div className="dialog__box__contents__body">{dialogBody}</div> - <div className="dialog__box__contents__button-container"> - <button className="dialog__box__contents__button-container__button" onClick={this.closeDialog}> - <span> - <FormattedMessage id="home.dialog.close" /> - </span> - </button> - </div> + <div className="dialog__box__contents__button-container" /> </div> </div> </div> diff --git a/yarn.lock b/yarn.lock index 8820642a27070f29460b409b87626ac173c298f5..6ae1ce2d8e2b6fb237724d975e27a2145a189ca7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -118,7 +118,7 @@ accepts@1.3.3: mime-types "~2.1.11" negotiator "0.6.1" -accepts@~1.3.4, accepts@~1.3.5: +accepts@~1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" dependencies: @@ -2007,18 +2007,14 @@ colormin@^1.0.5: css-color-names "0.0.4" has "^1.0.1" -colors@*: - version "1.2.1" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.1.tgz#f4a3d302976aaf042356ba1ade3b1a2c62d9d794" +colors@*, colors@^1.1.2, colors@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" colors@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" -colors@^1.1.2, colors@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" - combine-source-map@~0.7.1: version "0.7.2" resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.7.2.tgz#0870312856b307a87cc4ac486f3a9a62aeccc09e" @@ -2836,17 +2832,7 @@ error@^7.0.2: string-template "~0.2.1" xtend "~4.0.0" -es-abstract@^1.5.1: - version "1.11.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.11.0.tgz#cce87d518f0496893b1a30cd8461835535480681" - dependencies: - es-to-primitive "^1.1.1" - function-bind "^1.1.1" - has "^1.0.1" - is-callable "^1.1.3" - is-regex "^1.0.4" - -es-abstract@^1.7.0: +es-abstract@^1.5.1, es-abstract@^1.7.0: version "1.10.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864" dependencies: @@ -3076,42 +3062,7 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" -express@^4.10.7: - version "4.16.3" - resolved "https://registry.yarnpkg.com/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53" - dependencies: - accepts "~1.3.5" - array-flatten "1.1.1" - body-parser "1.18.2" - content-disposition "0.5.2" - content-type "~1.0.4" - cookie "0.3.1" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.1.1" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.2" - path-to-regexp "0.1.7" - proxy-addr "~2.0.3" - qs "6.5.1" - range-parser "~1.2.0" - safe-buffer "5.1.1" - send "0.16.2" - serve-static "1.13.2" - setprototypeof "1.1.0" - statuses "~1.4.0" - type-is "~1.6.16" - utils-merge "1.0.1" - vary "~1.1.2" - -express@^4.16.2: +express@^4.10.7, express@^4.16.2: version "4.16.2" resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c" dependencies: @@ -3317,18 +3268,6 @@ finalhandler@1.1.0: statuses "~1.3.1" unpipe "~1.0.0" -finalhandler@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.2" - statuses "~1.4.0" - unpipe "~1.0.0" - find-cache-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" @@ -3416,6 +3355,10 @@ form-data@~2.1.1: combined-stream "^1.0.5" mime-types "^2.1.12" +form-urlencoded@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/form-urlencoded/-/form-urlencoded-2.0.4.tgz#dbcd590a49ae35d5e9516bbba8567242d0291fe5" + forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" @@ -6391,7 +6334,7 @@ prop-types@^15.5.4, prop-types@^15.6.0: loose-envify "^1.3.1" object-assign "^4.1.1" -proxy-addr@~2.0.2, proxy-addr@~2.0.3: +proxy-addr@~2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341" dependencies: @@ -7159,7 +7102,7 @@ serve-static@1.13.1: parseurl "~1.3.2" send "0.16.1" -serve-static@1.13.2, serve-static@^1.10.0, serve-static@^1.8.0: +serve-static@^1.10.0, serve-static@^1.8.0: version "1.13.2" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" dependencies: @@ -7971,7 +7914,7 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-is@~1.6.15, type-is@~1.6.16: +type-is@~1.6.15: version "1.6.16" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" dependencies: