summaryrefslogtreecommitdiffstats
path: root/browser/components/newtab/content-src/components/DiscoveryStreamComponents/DSSignup/DSSignup.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/newtab/content-src/components/DiscoveryStreamComponents/DSSignup/DSSignup.jsx')
-rw-r--r--browser/components/newtab/content-src/components/DiscoveryStreamComponents/DSSignup/DSSignup.jsx168
1 files changed, 168 insertions, 0 deletions
diff --git a/browser/components/newtab/content-src/components/DiscoveryStreamComponents/DSSignup/DSSignup.jsx b/browser/components/newtab/content-src/components/DiscoveryStreamComponents/DSSignup/DSSignup.jsx
new file mode 100644
index 0000000000..b7e3205646
--- /dev/null
+++ b/browser/components/newtab/content-src/components/DiscoveryStreamComponents/DSSignup/DSSignup.jsx
@@ -0,0 +1,168 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import { actionCreators as ac } from "common/Actions.sys.mjs";
+import { LinkMenu } from "content-src/components/LinkMenu/LinkMenu";
+import { ContextMenuButton } from "content-src/components/ContextMenu/ContextMenuButton";
+import { ImpressionStats } from "../../DiscoveryStreamImpressionStats/ImpressionStats";
+import React from "react";
+import { SafeAnchor } from "../SafeAnchor/SafeAnchor";
+
+export class DSSignup extends React.PureComponent {
+ constructor(props) {
+ super(props);
+ this.state = {
+ active: false,
+ lastItem: false,
+ };
+ this.onMenuButtonUpdate = this.onMenuButtonUpdate.bind(this);
+ this.onLinkClick = this.onLinkClick.bind(this);
+ this.onMenuShow = this.onMenuShow.bind(this);
+ }
+
+ onMenuButtonUpdate(showContextMenu) {
+ if (!showContextMenu) {
+ this.setState({
+ active: false,
+ lastItem: false,
+ });
+ }
+ }
+
+ nextAnimationFrame() {
+ return new Promise(resolve =>
+ this.props.windowObj.requestAnimationFrame(resolve)
+ );
+ }
+
+ async onMenuShow() {
+ let { lastItem } = this.state;
+ // Wait for next frame before computing scrollMaxX to allow fluent menu strings to be visible
+ await this.nextAnimationFrame();
+ if (this.props.windowObj.scrollMaxX > 0) {
+ lastItem = true;
+ }
+ this.setState({
+ active: true,
+ lastItem,
+ });
+ }
+
+ onLinkClick() {
+ const { data } = this.props;
+ if (this.props.dispatch && data && data.spocs && data.spocs.length) {
+ const source = this.props.type.toUpperCase();
+ // Grab the first item in the array as we only have 1 spoc position.
+ const [spoc] = data.spocs;
+ this.props.dispatch(
+ ac.DiscoveryStreamUserEvent({
+ event: "CLICK",
+ source,
+ action_position: 0,
+ })
+ );
+
+ this.props.dispatch(
+ ac.ImpressionStats({
+ source,
+ click: 0,
+ tiles: [
+ {
+ id: spoc.id,
+ pos: 0,
+ ...(spoc.shim && spoc.shim.click
+ ? { shim: spoc.shim.click }
+ : {}),
+ },
+ ],
+ })
+ );
+ }
+ }
+
+ render() {
+ const { data, dispatch, type } = this.props;
+ if (!data || !data.spocs || !data.spocs[0]) {
+ return null;
+ }
+ // Grab the first item in the array as we only have 1 spoc position.
+ const [spoc] = data.spocs;
+ const { title, url, excerpt, flight_id, id, shim } = spoc;
+
+ const SIGNUP_CONTEXT_MENU_OPTIONS = [
+ "OpenInNewWindow",
+ "OpenInPrivateWindow",
+ "Separator",
+ "BlockUrl",
+ ...(flight_id ? ["ShowPrivacyInfo"] : []),
+ ];
+
+ const outerClassName = [
+ "ds-signup",
+ this.state.active && "active",
+ this.state.lastItem && "last-item",
+ ]
+ .filter(v => v)
+ .join(" ");
+
+ return (
+ <div className={outerClassName}>
+ <div className="ds-signup-content">
+ <span className="icon icon-small-spacer icon-mail"></span>
+ <span>
+ {title}{" "}
+ <SafeAnchor
+ className="ds-chevron-link"
+ dispatch={dispatch}
+ onLinkClick={this.onLinkClick}
+ url={url}
+ >
+ {excerpt}
+ </SafeAnchor>
+ </span>
+ <ImpressionStats
+ flightId={flight_id}
+ rows={[
+ {
+ id,
+ pos: 0,
+ shim: shim && shim.impression,
+ },
+ ]}
+ dispatch={dispatch}
+ source={type}
+ />
+ </div>
+ <ContextMenuButton
+ tooltip={"newtab-menu-content-tooltip"}
+ tooltipArgs={{ title }}
+ onUpdate={this.onMenuButtonUpdate}
+ >
+ <LinkMenu
+ dispatch={dispatch}
+ index={0}
+ source={type.toUpperCase()}
+ onShow={this.onMenuShow}
+ options={SIGNUP_CONTEXT_MENU_OPTIONS}
+ shouldSendImpressionStats={true}
+ userEvent={ac.DiscoveryStreamUserEvent}
+ site={{
+ referrer: "https://getpocket.com/recommendations",
+ title,
+ type,
+ url,
+ guid: id,
+ shim,
+ flight_id,
+ }}
+ />
+ </ContextMenuButton>
+ </div>
+ );
+ }
+}
+
+DSSignup.defaultProps = {
+ windowObj: window, // Added to support unit tests
+};