/* 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 React from "react"; import { batch } from "react-redux"; import { actionCreators as ac, actionTypes as at } from "common/Actions.mjs"; import { SectionsMgmtPanel } from "../SectionsMgmtPanel/SectionsMgmtPanel"; import { WallpaperCategories } from "../../WallpaperCategories/WallpaperCategories"; export class ContentSection extends React.PureComponent { constructor(props) { super(props); this.onPreferenceSelect = this.onPreferenceSelect.bind(this); // Refs are necessary for dynamically measuring drawer heights for slide animations this.topSitesDrawerRef = React.createRef(); this.pocketDrawerRef = React.createRef(); } inputUserEvent(eventSource, eventValue) { batch(() => { this.props.dispatch( ac.UserEvent({ event: "PREF_CHANGED", source: eventSource, value: { status: eventValue, menu_source: "CUSTOMIZE_MENU" }, }) ); // Dispatch unified widget telemetry for widget toggles. // Map the event source from the customize panel to the widget name // for the unified telemetry event. let widgetName; switch (eventSource) { case "WEATHER": widgetName = "weather"; break; case "WIDGET_LISTS": widgetName = "lists"; break; case "WIDGET_TIMER": widgetName = "focus_timer"; break; } if (widgetName) { const { widgetsMaximized, widgetsMayBeMaximized } = this.props.enabledWidgets; let widgetSize; if (widgetName === "weather") { if ( this.props.mayHaveWeatherForecast && this.props.weatherDisplay === "detailed" ) { widgetSize = widgetsMayBeMaximized && !widgetsMaximized ? "small" : "medium"; } else { widgetSize = "mini"; } } else { widgetSize = widgetsMayBeMaximized && !widgetsMaximized ? "small" : "medium"; } const data = { widget_name: widgetName, widget_source: "customize_panel", enabled: eventValue, widget_size: widgetSize, }; this.props.dispatch( ac.OnlyToMain({ type: at.WIDGETS_ENABLED, data, }) ); } }); } onPreferenceSelect(e) { // eventSource: WEATHER | TOP_SITES | TOP_STORIES | WIDGET_LISTS | WIDGET_TIMER const { preference, eventSource } = e.target.dataset; let value; if (e.target.nodeName === "SELECT") { value = parseInt(e.target.value, 10); } else if (e.target.nodeName === "INPUT") { value = e.target.checked; if (eventSource) { this.inputUserEvent(eventSource, value); } } else if (e.target.nodeName === "MOZ-TOGGLE") { value = e.target.pressed; if (eventSource) { this.inputUserEvent(eventSource, value); } } this.props.setPref(preference, value); } componentDidMount() { this.setDrawerMargins(); } componentDidUpdate() { this.setDrawerMargins(); } setDrawerMargins() { this.setDrawerMargin( `TOP_SITES`, this.props.enabledSections.topSitesEnabled ); this.setDrawerMargin( `TOP_STORIES`, this.props.enabledSections.pocketEnabled ); } setDrawerMargin(drawerID, isOpen) { let drawerRef; if (drawerID === `TOP_SITES`) { drawerRef = this.topSitesDrawerRef.current; } else if (drawerID === `TOP_STORIES`) { drawerRef = this.pocketDrawerRef.current; } else { return; } if (drawerRef) { // Use measured height if valid, otherwise use a large fallback // since overflow:hidden on the parent safely hides the drawer let drawerHeight = parseFloat(window.getComputedStyle(drawerRef)?.height) || 100; if (isOpen) { drawerRef.style.marginTop = "var(--space-small)"; } else { drawerRef.style.marginTop = `-${drawerHeight + 3}px`; } } } render() { const { enabledSections, enabledWidgets, pocketRegion, mayHaveInferredPersonalization, mayHaveWeather, mayHaveWidgets, mayHaveTimerWidget, mayHaveListsWidget, openPreferences, wallpapersEnabled, activeWallpaper, setPref, mayHaveTopicSections, exitEventFired, onSubpanelToggle, toggleSectionsMgmtPanel, showSectionsMgmtPanel, } = this.props; const { topSitesEnabled, pocketEnabled, weatherEnabled, showInferredPersonalizationEnabled, topSitesRowsCount, } = enabledSections; const { timerEnabled, listsEnabled } = enabledWidgets; return (
{wallpapersEnabled && ( <>
{/* If widgets section is visible, hide this divider */} {!mayHaveWidgets && ( )} )} {mayHaveWidgets && (

{/* Weather */} {mayHaveWeather && (
)} {/* Lists */} {mayHaveListsWidget && (
)} {/* Timer */} {mayHaveTimerWidget && (
)}
)}
{/* Note: If widgets are enabled, the weather toggle will be moved under Widgets subsection */} {!mayHaveWidgets && mayHaveWeather && (
)}
{pocketRegion && (
{(mayHaveInferredPersonalization || mayHaveTopicSections) && (
{mayHaveInferredPersonalization && (
)} {mayHaveTopicSections && ( )}
)}
)}
); } }