1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5import { LinkMenu } from "content-src/components/LinkMenu/LinkMenu";
6import { ContextMenuButton } from "content-src/components/ContextMenu/ContextMenuButton";
7import React from "react";
8
9export class DSLinkMenu extends React.PureComponent {
10  constructor(props) {
11    super(props);
12    this.onMenuUpdate = this.onMenuUpdate.bind(this);
13    this.onMenuShow = this.onMenuShow.bind(this);
14    this.contextMenuButtonRef = React.createRef();
15  }
16
17  onMenuUpdate(showContextMenu) {
18    if (!showContextMenu) {
19      const dsLinkMenuHostDiv = this.contextMenuButtonRef.current.parentElement;
20      dsLinkMenuHostDiv.parentElement.classList.remove("active", "last-item");
21    }
22  }
23
24  nextAnimationFrame() {
25    return new Promise(resolve =>
26      this.props.windowObj.requestAnimationFrame(resolve)
27    );
28  }
29
30  async onMenuShow() {
31    const dsLinkMenuHostDiv = this.contextMenuButtonRef.current.parentElement;
32    // Wait for next frame before computing scrollMaxX to allow fluent menu strings to be visible
33    await this.nextAnimationFrame();
34    if (this.props.windowObj.scrollMaxX > 0) {
35      dsLinkMenuHostDiv.parentElement.classList.add("last-item");
36    }
37    dsLinkMenuHostDiv.parentElement.classList.add("active");
38  }
39
40  render() {
41    const { index, dispatch } = this.props;
42    const TOP_STORIES_CONTEXT_MENU_OPTIONS = [
43      "CheckBookmarkOrArchive",
44      "CheckSavedToPocket",
45      "Separator",
46      "OpenInNewWindow",
47      "OpenInPrivateWindow",
48      "Separator",
49      "BlockUrl",
50      ...(this.props.flightId ? ["ShowPrivacyInfo"] : []),
51    ];
52    const type = this.props.type || "DISCOVERY_STREAM";
53    const title = this.props.title || this.props.source;
54
55    return (
56      <div>
57        <ContextMenuButton
58          refFunction={this.contextMenuButtonRef}
59          tooltip={"newtab-menu-content-tooltip"}
60          tooltipArgs={{ title }}
61          onUpdate={this.onMenuUpdate}
62        >
63          <LinkMenu
64            dispatch={dispatch}
65            index={index}
66            source={type.toUpperCase()}
67            onShow={this.onMenuShow}
68            options={TOP_STORIES_CONTEXT_MENU_OPTIONS}
69            shouldSendImpressionStats={true}
70            site={{
71              referrer: "https://getpocket.com/recommendations",
72              title: this.props.title,
73              type: this.props.type,
74              url: this.props.url,
75              guid: this.props.id,
76              pocket_id: this.props.pocket_id,
77              shim: this.props.shim,
78              bookmarkGuid: this.props.bookmarkGuid,
79              flight_id: this.props.flightId,
80            }}
81          />
82        </ContextMenuButton>
83      </div>
84    );
85  }
86}
87
88DSLinkMenu.defaultProps = {
89  windowObj: window, // Added to support unit tests
90};
91