tor-browser

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

Notifications.jsx (2220B)


      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, { useCallback, useEffect } from "react";
      6 import { useSelector } from "react-redux";
      7 import { actionCreators as ac, actionTypes as at } from "common/Actions.mjs";
      8 import { ReportContentToast } from "./Toasts/ReportContentToast";
      9 
     10 function Notifications({ dispatch }) {
     11  const toastQueue = useSelector(state => state.Notifications.toastQueue);
     12  const toastCounter = useSelector(state => state.Notifications.toastCounter);
     13 
     14  /**
     15   * Syncs {@link toastQueue} array so it can be used to
     16   * remove the toasts wrapper if there are none after a
     17   * toast is auto-hidden (animated out) via CSS.
     18   */
     19  const syncHiddenToastData = useCallback(() => {
     20    const toastId = toastQueue[toastQueue.length - 1];
     21    const queuedToasts = [...toastQueue].slice(1);
     22    dispatch(
     23      ac.OnlyToOneContent(
     24        {
     25          type: at.HIDE_TOAST_MESSAGE,
     26          data: {
     27            toastQueue: queuedToasts,
     28            toastCounter: queuedToasts.length,
     29            toastId,
     30            showNotifications: false,
     31          },
     32        },
     33        "ActivityStream:Content"
     34      )
     35    );
     36  }, [dispatch, toastQueue]);
     37 
     38  const getToast = useCallback(() => {
     39    // Note: This architecture could expand to support multiple toast notifications at once
     40    const latestToastItem = toastQueue[toastQueue.length - 1];
     41 
     42    if (!latestToastItem) {
     43      throw new Error("No toast found");
     44    }
     45 
     46    switch (latestToastItem) {
     47      case "reportSuccessToast":
     48        return (
     49          <ReportContentToast
     50            onDismissClick={syncHiddenToastData}
     51            onAnimationEnd={syncHiddenToastData}
     52            key={toastCounter}
     53          />
     54        );
     55      default:
     56        throw new Error(`Unexpected toast type: ${latestToastItem}`);
     57    }
     58  }, [syncHiddenToastData, toastCounter, toastQueue]);
     59 
     60  useEffect(() => {
     61    getToast();
     62  }, [toastQueue, getToast]);
     63 
     64  return toastQueue.length ? (
     65    <div className="notification-wrapper">{getToast()}</div>
     66  ) : (
     67    ""
     68  );
     69 }
     70 
     71 export { Notifications };