Commit 78adbe51 authored by scott's avatar scott
Browse files

Bug 1794020 - topsite promo tiles r=nanj

parent f2bdf17f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1582,6 +1582,8 @@ pref("browser.newtabpage.activity-stream.discoverystream.sponsored-collections.e
// Changes the spoc content.
pref("browser.newtabpage.activity-stream.discoverystream.spocAdTypes", "");
pref("browser.newtabpage.activity-stream.discoverystream.spocZoneIds", "");
pref("browser.newtabpage.activity-stream.discoverystream.spocTopsitesAdTypes", "");
pref("browser.newtabpage.activity-stream.discoverystream.spocTopsitesZoneIds", "");
pref("browser.newtabpage.activity-stream.discoverystream.spocSiteId", "");

pref("browser.newtabpage.activity-stream.discoverystream.sendToPocket.enabled", false);
+10 −0
Original line number Diff line number Diff line
@@ -35,6 +35,15 @@ add_task(async function test_firefox_home_without_policy_without_pocket() {
});

add_task(async function test_firefox_home_with_policy() {
  await SpecialPowers.pushPrefEnv({
    set: [
      [
        "browser.newtabpage.activity-stream.discoverystream.endpointSpocsClear",
        "",
      ],
    ],
  });

  await setupPolicyEngineWithJson({
    policies: {
      FirefoxHome: {
@@ -65,6 +74,7 @@ add_task(async function test_firefox_home_with_policy() {
    is(highlights, null, "Highlights section should not be there.");
  });
  BrowserTestUtils.removeTab(tab);
  await SpecialPowers.popPrefEnv();
});

add_task(async function test_firefoxhome_preferences_set() {
+4 −9
Original line number Diff line number Diff line
@@ -114,20 +114,15 @@ export class _DiscoveryStreamBase extends React.PureComponent {
      case "Highlights":
        return <Highlights />;
      case "TopSites":
        let promoAlignment;
        if (
          component.spocs &&
          component.spocs.positions &&
          component.spocs.positions.length
        ) {
          promoAlignment =
            component.spocs.positions[0].index === 0 ? "left" : "right";
        let positions = [];
        if (component?.spocs?.positions?.length) {
          positions = component.spocs.positions;
        }
        return (
          <TopSites
            header={component.header}
            data={component.data}
            promoAlignment={promoAlignment}
            promoPositions={positions}
          />
        );
      case "TextPromo":
+9 −68
Original line number Diff line number Diff line
@@ -4,7 +4,6 @@

import { connect } from "react-redux";
import { TopSites as OldTopSites } from "content-src/components/TopSites/TopSites";
import { TOP_SITES_MAX_SITES_PER_ROW } from "common/Reducers.jsm";
import React from "react";

export class _TopSites extends React.PureComponent {
@@ -31,37 +30,8 @@ export class _TopSites extends React.PureComponent {
    );
  }

  // Find the first empty or unpinned index we can place the SPOC in.
  // Return -1 if no available index and we should push it at the end.
  getFirstAvailableIndex(topSites, promoAlignment) {
    if (promoAlignment === "left") {
      return topSites.findIndex(topSite => !topSite || !topSite.isPinned);
    }

    // The row isn't full so we can push it to the end of the row.
    if (topSites.length < TOP_SITES_MAX_SITES_PER_ROW) {
      return -1;
    }

    // If the row is full, we can check the row first for unpinned topsites to replace.
    // Else we can check after the row. This behavior is how unpinned topsites move while drag and drop.
    let endOfRow = TOP_SITES_MAX_SITES_PER_ROW - 1;
    for (let i = endOfRow; i >= 0; i--) {
      if (!topSites[i] || !topSites[i].isPinned) {
        return i;
      }
    }

    for (let i = endOfRow + 1; i < topSites.length; i++) {
      if (!topSites[i] || !topSites[i].isPinned) {
        return i;
      }
    }

    return -1;
  }

  insertSpocContent(TopSites, data, promoAlignment) {
  // For the time being we only support 1 position.
  insertSpocContent(TopSites, data, promoPosition) {
    if (
      !TopSites.rows ||
      TopSites.rows.length === 0 ||
@@ -91,51 +61,22 @@ export class _TopSites extends React.PureComponent {
      // For now we are assuming position based on intended position.
      // Actual position can shift based on other content.
      // We also hard code left and right to be 0 and 7.
      // We send the intended postion in the ping.
      pos: promoAlignment === "left" ? 0 : 7,
      // We send the intended position in the ping.
      pos: promoPosition,
    };

    const firstAvailableIndex = this.getFirstAvailableIndex(
      topSites,
      promoAlignment
    );

    if (firstAvailableIndex === -1) {
      topSites.push(link);
    } else {
      // Normal insertion will not work since pinned topsites are in their correct index already
      // Similar logic is done to handle drag and drop with pinned topsites in TopSite.jsx

      let shiftedTopSite = topSites[firstAvailableIndex];
      let index = firstAvailableIndex + 1;

      // Shift unpinned topsites to the right by finding the next unpinned topsite to replace
      while (shiftedTopSite) {
        if (index === topSites.length) {
          topSites.push(shiftedTopSite);
          shiftedTopSite = null;
        } else if (topSites[index] && topSites[index].isPinned) {
          index += 1;
        } else {
          const nextTopSite = topSites[index];
          topSites[index] = shiftedTopSite;
          shiftedTopSite = nextTopSite;
          index += 1;
        }
      }

      topSites[firstAvailableIndex] = link;
    }
    const replaceCount = topSites[promoPosition]?.show_sponsored_label ? 1 : 0;
    topSites.splice(promoPosition, replaceCount, link);

    return { ...TopSites, rows: topSites };
  }

  render() {
    const { header = {}, data, promoAlignment, TopSites } = this.props;
    const { header = {}, data, promoPositions, TopSites } = this.props;

    const TopSitesWithSpoc =
      TopSites && data && promoAlignment
        ? this.insertSpocContent(TopSites, data, promoAlignment)
      TopSites && data && promoPositions?.length
        ? this.insertSpocContent(TopSites, data, promoPositions[0].index)
        : null;

    return (
+15 −67
Original line number Diff line number Diff line
@@ -13456,7 +13456,6 @@ const selectLayoutRender = ({




class TopSites_TopSites_TopSites extends (external_React_default()).PureComponent {
  // Find a SPOC that doesn't already exist in User's TopSites
  getFirstAvailableSpoc(topSites, data) {
@@ -13472,40 +13471,12 @@ class TopSites_TopSites_TopSites extends (external_React_default()).PureComponen
    // Spoc domains are in the format 'sponsorname.com'

    return spocs.find(spoc => !userTopSites.has(spoc.url) && !userTopSites.has(`http://${spoc.domain}`) && !userTopSites.has(`https://${spoc.domain}`) && !userTopSites.has(`http://www.${spoc.domain}`) && !userTopSites.has(`https://www.${spoc.domain}`));
  } // Find the first empty or unpinned index we can place the SPOC in.
  // Return -1 if no available index and we should push it at the end.


  getFirstAvailableIndex(topSites, promoAlignment) {
    if (promoAlignment === "left") {
      return topSites.findIndex(topSite => !topSite || !topSite.isPinned);
    } // The row isn't full so we can push it to the end of the row.


    if (topSites.length < TOP_SITES_MAX_SITES_PER_ROW) {
      return -1;
    } // If the row is full, we can check the row first for unpinned topsites to replace.
    // Else we can check after the row. This behavior is how unpinned topsites move while drag and drop.

  } // For the time being we only support 1 position.

    let endOfRow = TOP_SITES_MAX_SITES_PER_ROW - 1;

    for (let i = endOfRow; i >= 0; i--) {
      if (!topSites[i] || !topSites[i].isPinned) {
        return i;
      }
    }

    for (let i = endOfRow + 1; i < topSites.length; i++) {
      if (!topSites[i] || !topSites[i].isPinned) {
        return i;
      }
    }
  insertSpocContent(TopSites, data, promoPosition) {
    var _topSites$promoPositi;

    return -1;
  }

  insertSpocContent(TopSites, data, promoAlignment) {
    if (!TopSites.rows || TopSites.rows.length === 0 || !data.spocs || data.spocs.length === 0) {
      return null;
    }
@@ -13530,36 +13501,11 @@ class TopSites_TopSites_TopSites extends (external_React_default()).PureComponen
      // For now we are assuming position based on intended position.
      // Actual position can shift based on other content.
      // We also hard code left and right to be 0 and 7.
      // We send the intended postion in the ping.
      pos: promoAlignment === "left" ? 0 : 7
      // We send the intended position in the ping.
      pos: promoPosition
    };
    const firstAvailableIndex = this.getFirstAvailableIndex(topSites, promoAlignment);

    if (firstAvailableIndex === -1) {
      topSites.push(link);
    } else {
      // Normal insertion will not work since pinned topsites are in their correct index already
      // Similar logic is done to handle drag and drop with pinned topsites in TopSite.jsx
      let shiftedTopSite = topSites[firstAvailableIndex];
      let index = firstAvailableIndex + 1; // Shift unpinned topsites to the right by finding the next unpinned topsite to replace

      while (shiftedTopSite) {
        if (index === topSites.length) {
          topSites.push(shiftedTopSite);
          shiftedTopSite = null;
        } else if (topSites[index] && topSites[index].isPinned) {
          index += 1;
        } else {
          const nextTopSite = topSites[index];
          topSites[index] = shiftedTopSite;
          shiftedTopSite = nextTopSite;
          index += 1;
        }
      }

      topSites[firstAvailableIndex] = link;
    }

    const replaceCount = (_topSites$promoPositi = topSites[promoPosition]) !== null && _topSites$promoPositi !== void 0 && _topSites$promoPositi.show_sponsored_label ? 1 : 0;
    topSites.splice(promoPosition, replaceCount, link);
    return { ...TopSites,
      rows: topSites
    };
@@ -13569,10 +13515,10 @@ class TopSites_TopSites_TopSites extends (external_React_default()).PureComponen
    const {
      header = {},
      data,
      promoAlignment,
      promoPositions,
      TopSites
    } = this.props;
    const TopSitesWithSpoc = TopSites && data && promoAlignment ? this.insertSpocContent(TopSites, data, promoAlignment) : null;
    const TopSitesWithSpoc = TopSites && data && promoPositions !== null && promoPositions !== void 0 && promoPositions.length ? this.insertSpocContent(TopSites, data, promoPositions[0].index) : null;
    return /*#__PURE__*/external_React_default().createElement("div", {
      className: `ds-top-sites ${TopSitesWithSpoc ? "top-sites-spoc" : ""}`
    }, /*#__PURE__*/external_React_default().createElement(TopSites_TopSites, {
@@ -13679,21 +13625,23 @@ class _DiscoveryStreamBase extends (external_React_default()).PureComponent {
  }

  renderComponent(component, embedWidth) {
    var _component$spocs, _component$spocs$posi;

    switch (component.type) {
      case "Highlights":
        return /*#__PURE__*/external_React_default().createElement(Highlights, null);

      case "TopSites":
        let promoAlignment;
        let positions = [];

        if (component.spocs && component.spocs.positions && component.spocs.positions.length) {
          promoAlignment = component.spocs.positions[0].index === 0 ? "left" : "right";
        if (component !== null && component !== void 0 && (_component$spocs = component.spocs) !== null && _component$spocs !== void 0 && (_component$spocs$posi = _component$spocs.positions) !== null && _component$spocs$posi !== void 0 && _component$spocs$posi.length) {
          positions = component.spocs.positions;
        }

        return /*#__PURE__*/external_React_default().createElement(DiscoveryStreamComponents_TopSites_TopSites_TopSites, {
          header: component.header,
          data: component.data,
          promoAlignment: promoAlignment
          promoPositions: positions
        });

      case "TextPromo":
Loading