tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ContentSection.jsx (11847B)


      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 
      5 import React from "react";
      6 import { actionCreators as ac } from "common/Actions.mjs";
      7 import { SectionsMgmtPanel } from "../SectionsMgmtPanel/SectionsMgmtPanel";
      8 import { WallpaperCategories } from "../../WallpaperCategories/WallpaperCategories";
      9 
     10 export class ContentSection extends React.PureComponent {
     11  constructor(props) {
     12    super(props);
     13    this.onPreferenceSelect = this.onPreferenceSelect.bind(this);
     14 
     15    // Refs are necessary for dynamically measuring drawer heights for slide animations
     16    this.topSitesDrawerRef = React.createRef();
     17    this.pocketDrawerRef = React.createRef();
     18  }
     19 
     20  inputUserEvent(eventSource, eventValue) {
     21    this.props.dispatch(
     22      ac.UserEvent({
     23        event: "PREF_CHANGED",
     24        source: eventSource,
     25        value: { status: eventValue, menu_source: "CUSTOMIZE_MENU" },
     26      })
     27    );
     28  }
     29 
     30  onPreferenceSelect(e) {
     31    // eventSource: WEATHER | TOP_SITES | TOP_STORIES | WIDGET_LISTS | WIDGET_TIMER
     32    const { preference, eventSource } = e.target.dataset;
     33    let value;
     34    if (e.target.nodeName === "SELECT") {
     35      value = parseInt(e.target.value, 10);
     36    } else if (e.target.nodeName === "INPUT") {
     37      value = e.target.checked;
     38      if (eventSource) {
     39        this.inputUserEvent(eventSource, value);
     40      }
     41    } else if (e.target.nodeName === "MOZ-TOGGLE") {
     42      value = e.target.pressed;
     43      if (eventSource) {
     44        this.inputUserEvent(eventSource, value);
     45      }
     46    }
     47    this.props.setPref(preference, value);
     48  }
     49 
     50  componentDidMount() {
     51    this.setDrawerMargins();
     52  }
     53 
     54  componentDidUpdate() {
     55    this.setDrawerMargins();
     56  }
     57 
     58  setDrawerMargins() {
     59    this.setDrawerMargin(
     60      `TOP_SITES`,
     61      this.props.enabledSections.topSitesEnabled
     62    );
     63    this.setDrawerMargin(
     64      `TOP_STORIES`,
     65      this.props.enabledSections.pocketEnabled
     66    );
     67  }
     68 
     69  setDrawerMargin(drawerID, isOpen) {
     70    let drawerRef;
     71 
     72    if (drawerID === `TOP_SITES`) {
     73      drawerRef = this.topSitesDrawerRef.current;
     74    } else if (drawerID === `TOP_STORIES`) {
     75      drawerRef = this.pocketDrawerRef.current;
     76    } else {
     77      return;
     78    }
     79 
     80    if (drawerRef) {
     81      // Use measured height if valid, otherwise use a large fallback
     82      // since overflow:hidden on the parent safely hides the drawer
     83      let drawerHeight =
     84        parseFloat(window.getComputedStyle(drawerRef)?.height) || 100;
     85 
     86      if (isOpen) {
     87        drawerRef.style.marginTop = "var(--space-small)";
     88      } else {
     89        drawerRef.style.marginTop = `-${drawerHeight + 3}px`;
     90      }
     91    }
     92  }
     93 
     94  render() {
     95    const {
     96      enabledSections,
     97      enabledWidgets,
     98      pocketRegion,
     99      mayHaveInferredPersonalization,
    100      mayHaveWeather,
    101      mayHaveWidgets,
    102      mayHaveTimerWidget,
    103      mayHaveListsWidget,
    104      openPreferences,
    105      wallpapersEnabled,
    106      activeWallpaper,
    107      setPref,
    108      mayHaveTopicSections,
    109      exitEventFired,
    110      onSubpanelToggle,
    111      toggleSectionsMgmtPanel,
    112      showSectionsMgmtPanel,
    113    } = this.props;
    114    const {
    115      topSitesEnabled,
    116      pocketEnabled,
    117      weatherEnabled,
    118      showInferredPersonalizationEnabled,
    119      topSitesRowsCount,
    120    } = enabledSections;
    121    const { timerEnabled, listsEnabled } = enabledWidgets;
    122 
    123    return (
    124      <div className="home-section">
    125        {wallpapersEnabled && (
    126          <>
    127            <div className="wallpapers-section">
    128              <WallpaperCategories
    129                setPref={setPref}
    130                activeWallpaper={activeWallpaper}
    131                exitEventFired={exitEventFired}
    132                onSubpanelToggle={onSubpanelToggle}
    133              />
    134            </div>
    135            {/* If widgets section is visible, hide this divider */}
    136            {!mayHaveWidgets && (
    137              <span className="divider" role="separator"></span>
    138            )}
    139          </>
    140        )}
    141        {mayHaveWidgets && (
    142          <div className="widgets-section">
    143            <div className="category-header">
    144              <h2 data-l10n-id="newtab-custom-widget-section-title"></h2>
    145            </div>
    146            <div className="settings-widgets">
    147              {/* Weather */}
    148              {mayHaveWeather && (
    149                <div id="weather-section" className="section">
    150                  <moz-toggle
    151                    id="weather-toggle"
    152                    pressed={weatherEnabled || null}
    153                    onToggle={this.onPreferenceSelect}
    154                    data-preference="showWeather"
    155                    data-eventSource="WEATHER"
    156                    data-l10n-id="newtab-custom-widget-weather-toggle"
    157                  />
    158                </div>
    159              )}
    160 
    161              {/* Lists */}
    162              {mayHaveListsWidget && (
    163                <div id="lists-widget-section" className="section">
    164                  <moz-toggle
    165                    id="lists-toggle"
    166                    pressed={listsEnabled || null}
    167                    onToggle={this.onPreferenceSelect}
    168                    data-preference="widgets.lists.enabled"
    169                    data-eventSource="WIDGET_LISTS"
    170                    data-l10n-id="newtab-custom-widget-lists-toggle"
    171                  />
    172                </div>
    173              )}
    174 
    175              {/* Timer */}
    176              {mayHaveTimerWidget && (
    177                <div id="timer-widget-section" className="section">
    178                  <moz-toggle
    179                    id="timer-toggle"
    180                    pressed={timerEnabled || null}
    181                    onToggle={this.onPreferenceSelect}
    182                    data-preference="widgets.focusTimer.enabled"
    183                    data-eventSource="WIDGET_TIMER"
    184                    data-l10n-id="newtab-custom-widget-timer-toggle"
    185                  />
    186                </div>
    187              )}
    188              <span className="divider" role="separator"></span>
    189            </div>
    190          </div>
    191        )}
    192        <div className="settings-toggles">
    193          {/* Note: If widgets are enabled, the weather toggle will be moved under Widgets subsection */}
    194          {!mayHaveWidgets && mayHaveWeather && (
    195            <div id="weather-section" className="section">
    196              <moz-toggle
    197                id="weather-toggle"
    198                pressed={weatherEnabled || null}
    199                onToggle={this.onPreferenceSelect}
    200                data-preference="showWeather"
    201                data-eventSource="WEATHER"
    202                data-l10n-id="newtab-custom-weather-toggle"
    203              />
    204            </div>
    205          )}
    206 
    207          <div id="shortcuts-section" className="section">
    208            <moz-toggle
    209              id="shortcuts-toggle"
    210              pressed={topSitesEnabled || null}
    211              onToggle={this.onPreferenceSelect}
    212              data-preference="feeds.topsites"
    213              data-eventSource="TOP_SITES"
    214              data-l10n-id="newtab-custom-shortcuts-toggle"
    215            >
    216              <div slot="nested">
    217                <div className="more-info-top-wrapper">
    218                  <div
    219                    className="more-information"
    220                    ref={this.topSitesDrawerRef}
    221                  >
    222                    <select
    223                      id="row-selector"
    224                      className="selector"
    225                      name="row-count"
    226                      data-preference="topSitesRows"
    227                      value={topSitesRowsCount}
    228                      onChange={this.onPreferenceSelect}
    229                      disabled={!topSitesEnabled}
    230                      aria-labelledby="custom-shortcuts-title"
    231                    >
    232                      <option
    233                        value="1"
    234                        data-l10n-id="newtab-custom-row-selector"
    235                        data-l10n-args='{"num": 1}'
    236                      />
    237                      <option
    238                        value="2"
    239                        data-l10n-id="newtab-custom-row-selector"
    240                        data-l10n-args='{"num": 2}'
    241                      />
    242                      <option
    243                        value="3"
    244                        data-l10n-id="newtab-custom-row-selector"
    245                        data-l10n-args='{"num": 3}'
    246                      />
    247                      <option
    248                        value="4"
    249                        data-l10n-id="newtab-custom-row-selector"
    250                        data-l10n-args='{"num": 4}'
    251                      />
    252                    </select>
    253                  </div>
    254                </div>
    255              </div>
    256            </moz-toggle>
    257          </div>
    258 
    259          {pocketRegion && (
    260            <div id="pocket-section" className="section">
    261              <moz-toggle
    262                id="pocket-toggle"
    263                pressed={pocketEnabled || null}
    264                onToggle={this.onPreferenceSelect}
    265                aria-describedby="custom-pocket-subtitle"
    266                data-preference="feeds.section.topstories"
    267                data-eventSource="TOP_STORIES"
    268                {...(mayHaveInferredPersonalization
    269                  ? {
    270                      "data-l10n-id":
    271                        "newtab-custom-stories-personalized-toggle",
    272                    }
    273                  : {
    274                      "data-l10n-id": "newtab-custom-stories-toggle",
    275                    })}
    276              >
    277                <div slot="nested">
    278                  {(mayHaveInferredPersonalization || mayHaveTopicSections) && (
    279                    <div className="more-info-pocket-wrapper">
    280                      <div
    281                        className="more-information"
    282                        ref={this.pocketDrawerRef}
    283                      >
    284                        {mayHaveInferredPersonalization && (
    285                          <div className="check-wrapper" role="presentation">
    286                            <input
    287                              id="inferred-personalization"
    288                              className="customize-menu-checkbox"
    289                              disabled={!pocketEnabled}
    290                              checked={showInferredPersonalizationEnabled}
    291                              type="checkbox"
    292                              onChange={this.onPreferenceSelect}
    293                              data-preference="discoverystream.sections.personalization.inferred.user.enabled"
    294                              data-eventSource="INFERRED_PERSONALIZATION"
    295                            />
    296                            <label
    297                              className="customize-menu-checkbox-label"
    298                              htmlFor="inferred-personalization"
    299                              data-l10n-id="newtab-custom-stories-personalized-checkbox-label"
    300                            />
    301                          </div>
    302                        )}
    303                        {mayHaveTopicSections && (
    304                          <SectionsMgmtPanel
    305                            exitEventFired={exitEventFired}
    306                            pocketEnabled={pocketEnabled}
    307                            onSubpanelToggle={onSubpanelToggle}
    308                            togglePanel={toggleSectionsMgmtPanel}
    309                            showPanel={showSectionsMgmtPanel}
    310                          />
    311                        )}
    312                      </div>
    313                    </div>
    314                  )}
    315                </div>
    316              </moz-toggle>
    317            </div>
    318          )}
    319        </div>
    320 
    321        <span className="divider" role="separator"></span>
    322 
    323        <div>
    324          <button
    325            id="settings-link"
    326            className="external-link"
    327            onClick={openPreferences}
    328            data-l10n-id="newtab-custom-settings"
    329          />
    330        </div>
    331      </div>
    332    );
    333  }
    334 }