Skip to content

Commit

Permalink
feat: new toasts 🔥🍞 (#2729)
Browse files Browse the repository at this point in the history
* feat: react-hot-toasts 🍞

* fix: remove imports

* feat: add close icon for toats which are not immediately closed
  • Loading branch information
reneaaron authored Sep 7, 2023
1 parent 2ad21ee commit 25ce059
Show file tree
Hide file tree
Showing 65 changed files with 170 additions and 132 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@
"react": "^18.2.0",
"react-confetti": "^6.1.0",
"react-dom": "^18.2.0",
"react-hot-toast": "^2.4.1",
"react-i18next": "^12.3.1",
"react-loading-skeleton": "^3.3.1",
"react-modal": "^3.16.1",
"react-qr-code": "^2.0.12",
"react-router-dom": "^6.14.2",
"react-toastify": "^9.1.3",
"slip77": "^0.2.0",
"stream": "^0.0.2",
"tailwindcss": "^3.3.3",
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/InputCopyButton/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CopyIcon as CopyFilledIcon } from "@bitcoin-design/bitcoin-icons-react/filled";
import { CopyIcon } from "@bitcoin-design/bitcoin-icons-react/outline";
import { useState } from "react";
import { toast } from "react-toastify";
import toast from "~/app/components/Toast";
import { classNames } from "~/app/utils";

type Props = {
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/QrcodeScanner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { QrCodeIcon } from "@bitcoin-design/bitcoin-icons-react/filled";
import { Html5Qrcode, Html5QrcodeScannerState } from "html5-qrcode";
import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "react-toastify";
import toast from "~/app/components/Toast";

import Button from "../Button";

Expand Down
2 changes: 1 addition & 1 deletion src/app/components/SitePreferences/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Toggle from "@components/form/Toggle";
import type { FormEvent } from "react";
import { Fragment, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "react-toastify";
import toast from "~/app/components/Toast";
import { useAccount } from "~/app/context/AccountContext";
import { useSettings } from "~/app/context/SettingsContext";
import { PreferencesIcon } from "~/app/icons";
Expand Down
12 changes: 12 additions & 0 deletions src/app/components/Toast/Toaster.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Toaster as HotToaster } from "react-hot-toast";

export default function Toaster() {
return (
<HotToaster
position="bottom-center"
toastOptions={{
duration: 4_000,
}}
/>
);
}
63 changes: 63 additions & 0 deletions src/app/components/Toast/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { CrossIcon } from "@bitcoin-design/bitcoin-icons-react/outline";
import { Transition } from "@headlessui/react";
import { ReactNode } from "react";
import {
CheckmarkIcon,
ErrorIcon,
ToastOptions,
toast as hotToast,
} from "react-hot-toast";

type ToastType = "error" | "success";

interface ToastMethods {
success: (message: string | ReactNode, options?: ToastOptions) => void;
error: (message: string | ReactNode, options?: ToastOptions) => void;
custom: (
children: ReactNode,
type: ToastType,
options?: ToastOptions
) => void;
}

const toast: ToastMethods = {
success: (message: string | ReactNode, options?: ToastOptions) => {
toast.custom(message, "success", options);
},
error: (message: string | ReactNode, options?: ToastOptions) => {
toast.custom(message, "error", { duration: options?.duration ?? 8_000 });
},
custom: (children: ReactNode, type: ToastType, options?: ToastOptions) => {
hotToast.custom(
(t: { visible: boolean; id: string }) => (
<Transition
enter="transform transition duration-[400ms]"
enterFrom="opacity-0 scale-0"
enterTo="opacity-100 scale-1"
leave="transform duration-200 transition ease-in-out"
leaveFrom="opacity-100 scale-1"
leaveTo="opacity-0 scale-0"
show={t.visible}
>
<div className="bg-white dark:bg-surface-02dp px-4 py-3 drop-shadow-lg rounded-lg overflow-hidden flex flex-row items-center gap-3 text-gray-800 dark:text-neutral-200">
<div className="shrink-0">
{type == "success" && <CheckmarkIcon />}
{type == "error" && <ErrorIcon />}
</div>
<div>{children}</div>
{/* Add close icons for toasts that are displayed for a longer time */}
{options?.duration && options?.duration > 10_000 && (
<CrossIcon
className="w-4 h-4 cursor-pointer"
onClick={() => hotToast.dismiss(t.id)}
/>
)}
</div>
</Transition>
),
options
);
},
};

export default toast;
7 changes: 4 additions & 3 deletions src/app/components/toasts/ConnectionErrorToast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ export default function ConnectionErrorToast({
const { t: tCommon } = useTranslation("common");
return (
<>
<p className="mb-2">
{tCommon("errors.connection_failed")}
<br />(<span className="italic text-sm">{message}</span>)
<p className="text-sm font-medium">
{tCommon("errors.connection_failed")} (
<span className="text-sm">{message}</span>)
</p>

<p className="my-2 text-sm">{t("what_you_can_do")}</p>
<ul className="list-disc text-sm list-inside">
<li>{t("double_check")}</li>
Expand Down
26 changes: 0 additions & 26 deletions src/app/components/toasts/LoginFailedToast.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion src/app/context/AccountContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
useEffect,
useState,
} from "react";
import { toast } from "react-toastify";
import toast from "~/app/components/Toast";
import { useSettings } from "~/app/context/SettingsContext";
import api from "~/common/lib/api";
import msg from "~/common/lib/msg";
Expand Down
2 changes: 1 addition & 1 deletion src/app/context/SettingsContext.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import dayjs from "dayjs";
import i18n from "i18next";
import { createContext, useContext, useEffect, useRef, useState } from "react";
import { toast } from "react-toastify";
import toast from "~/app/components/Toast";
import { setTheme } from "~/app/utils";
import { ACCOUNT_CURRENCIES, CURRENCIES } from "~/common/constants";
import api from "~/common/lib/api";
Expand Down
2 changes: 1 addition & 1 deletion src/app/hooks/useInvoices.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import dayjs from "dayjs";
import { useCallback, useState } from "react";
import { toast } from "react-toastify";
import toast from "~/app/components/Toast";
import { useSettings } from "~/app/context/SettingsContext";
import api from "~/common/lib/api";
import { Transaction } from "~/types";
Expand Down
2 changes: 1 addition & 1 deletion src/app/hooks/useTransactions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useCallback, useState } from "react";
import { toast } from "react-toastify";
import toast from "~/app/components/Toast";
import { useSettings } from "~/app/context/SettingsContext";
import { convertPaymentsToTransactions } from "~/app/utils/payments";
import api from "~/common/lib/api";
Expand Down
11 changes: 3 additions & 8 deletions src/app/router/Options/Options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import Transactions from "@screens/Transactions";
import Unlock from "@screens/Unlock";
import { useTranslation } from "react-i18next";
import { HashRouter, Navigate, Outlet, Route, Routes } from "react-router-dom";
import { ToastContainer } from "react-toastify";
import AccountDetailLayout from "~/app/components/AccountDetailLayout";
import ScrollToTop from "~/app/components/ScrollToTop";
import Toaster from "~/app/components/Toast/Toaster";
import Providers from "~/app/context/Providers";
import RequireAuth from "~/app/router/RequireAuth";
import { getConnectorRoutes, renderRoutes } from "~/app/router/connectorRoutes";
Expand Down Expand Up @@ -148,7 +148,7 @@ function Options() {
element={
<>
<Unlock />
<ToastContainer autoClose={10000} hideProgressBar={true} />
<Toaster />
</>
}
/>
Expand All @@ -170,12 +170,7 @@ const Layout = () => {
</Navbar.Link>
<Navbar.Link href="/wallet">{tCommon("wallet")}</Navbar.Link>
</Navbar>
<ToastContainer
autoClose={15000}
hideProgressBar={true}
className="w-fit max-w-2xl"
/>

<Toaster />
<Outlet />
</div>
);
Expand Down
1 change: 0 additions & 1 deletion src/app/router/Options/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { createRoot } from "react-dom/client";
import "react-loading-skeleton/dist/skeleton.css";
import Modal from "react-modal";
import "react-toastify/dist/ReactToastify.css";
import "~/app/styles/index.css";
import { setTheme } from "~/app/utils";
import "~/i18n/i18nConfig";
Expand Down
8 changes: 4 additions & 4 deletions src/app/router/Popup/Popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import LNURLPay from "@screens/LNURLPay";
import LNURLWithdraw from "@screens/LNURLWithdraw";
import Receive from "@screens/Receive";
import Send from "@screens/Send";
import ScanQRCode from "~/app/screens/ScanQRCode";
import Unlock from "@screens/Unlock";
import { HashRouter, Outlet, Route, Routes } from "react-router-dom";
import { ToastContainer } from "react-toastify";
import Providers from "~/app/context/Providers";
import LNURLRedeem from "~/app/screens/LNURLRedeem";
import OnChainReceive from "~/app/screens/OnChainReceive";
import ScanQRCode from "~/app/screens/ScanQRCode";
import SendToBitcoinAddress from "~/app/screens/SendToBitcoinAddress";

import Toaster from "~/app/components/Toast/Toaster";
import RequireAuth from "../RequireAuth";

function Popup() {
Expand Down Expand Up @@ -54,7 +54,7 @@ function Popup() {
element={
<>
<Unlock />
<ToastContainer autoClose={10000} hideProgressBar={true} />
<Toaster />
</>
}
/>
Expand All @@ -71,7 +71,7 @@ const Layout = () => {

<main className="flex flex-col grow min-h-0">
<Outlet />
<ToastContainer autoClose={10000} hideProgressBar={true} />
<Toaster />
</main>
</div>
);
Expand Down
1 change: 0 additions & 1 deletion src/app/router/Popup/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { createRoot } from "react-dom/client";
import "react-loading-skeleton/dist/skeleton.css";
import "react-toastify/dist/ReactToastify.css";
import "~/app/styles/index.css";
import { setTheme } from "~/app/utils";
import "~/i18n/i18nConfig";
Expand Down
6 changes: 3 additions & 3 deletions src/app/router/Prompt/Prompt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import NostrConfirmSignMessage from "@screens/Nostr/ConfirmSignMessage";
import NostrConfirmSignSchnorr from "@screens/Nostr/ConfirmSignSchnorr";
import Unlock from "@screens/Unlock";
import { HashRouter, Navigate, Outlet, Route, Routes } from "react-router-dom";
import { ToastContainer } from "react-toastify";
import AlbyLogo from "~/app/components/AlbyLogo";
import Toaster from "~/app/components/Toast/Toaster";
import Providers from "~/app/context/Providers";
import RequireAuth from "~/app/router/RequireAuth";
import BitcoinConfirmGetAddress from "~/app/screens/Bitcoin/ConfirmGetAddress";
Expand Down Expand Up @@ -140,7 +140,7 @@ function Prompt() {
element={
<>
<Unlock />
<ToastContainer autoClose={10000} hideProgressBar={true} />
<Toaster />
</>
}
/>
Expand All @@ -153,7 +153,7 @@ function Prompt() {
const Layout = () => {
return (
<>
<ToastContainer autoClose={10000} hideProgressBar={true} />
<Toaster />
<div className="px-4 py-2 justify-between items-center bg-white flex border-b border-gray-200 dark:bg-surface-02dp dark:border-neutral-500 gap-5">
<div className="w-24 shrink-0">
<AlbyLogo />
Expand Down
1 change: 0 additions & 1 deletion src/app/router/Prompt/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { createRoot } from "react-dom/client";
import "react-loading-skeleton/dist/skeleton.css";
import "react-toastify/dist/ReactToastify.css";
import "~/app/styles/index.css";
import { setTheme } from "~/app/utils";
import "~/i18n/i18nConfig";
Expand Down
8 changes: 2 additions & 6 deletions src/app/router/Welcome/Welcome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import ChooseConnector from "@screens/connectors/ChooseConnector";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Outlet, Route, HashRouter as Router, Routes } from "react-router-dom";
import { ToastContainer } from "react-toastify";
import Container from "~/app/components/Container";
import Toaster from "~/app/components/Toast/Toaster";
import { SettingsProvider } from "~/app/context/SettingsContext";
import { getConnectorRoutes, renderRoutes } from "~/app/router/connectorRoutes";
import ChooseConnectorPath from "~/app/screens/connectors/ChooseConnectorPath";
Expand All @@ -18,11 +18,7 @@ function Welcome() {
return (
<SettingsProvider>
<Router>
<ToastContainer
autoClose={15000}
hideProgressBar={true}
className="w-fit max-w-2xl"
/>
<Toaster />
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<SetPassword />} />
Expand Down
1 change: 0 additions & 1 deletion src/app/router/Welcome/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { createRoot } from "react-dom/client";
import "react-loading-skeleton/dist/skeleton.css";
import Modal from "react-modal";
import "react-toastify/dist/ReactToastify.css";
import "~/app/styles/index.css";
import { setTheme } from "~/app/utils";
import "~/i18n/i18nConfig";
Expand Down
2 changes: 1 addition & 1 deletion src/app/screens/Accounts/BackupMnemonic/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import Loading from "@components/Loading";
import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate, useParams } from "react-router-dom";
import { toast } from "react-toastify";
import Button from "~/app/components/Button";
import { ContentBox } from "~/app/components/ContentBox";
import toast from "~/app/components/Toast";
import MnemonicDescription from "~/app/components/mnemonic/MnemonicDescription";
import MnemonicInputs from "~/app/components/mnemonic/MnemonicInputs";
import api from "~/common/lib/api";
Expand Down
2 changes: 1 addition & 1 deletion src/app/screens/Accounts/Detail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import { useCallback, useEffect, useRef, useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import QRCode from "react-qr-code";
import { Link, useNavigate, useParams } from "react-router-dom";
import { toast } from "react-toastify";
import Alert from "~/app/components/Alert";
import Badge from "~/app/components/Badge";
import Hyperlink from "~/app/components/Hyperlink";
import InputCopyButton from "~/app/components/InputCopyButton";
import MenuDivider from "~/app/components/Menu/MenuDivider";
import Modal from "~/app/components/Modal";
import toast from "~/app/components/Toast";
import Select from "~/app/components/form/Select";
import Toggle from "~/app/components/form/Toggle";
import { useAccount } from "~/app/context/AccountContext";
Expand Down
2 changes: 1 addition & 1 deletion src/app/screens/Accounts/GenerateMnemonic/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import Loading from "@components/Loading";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate, useParams } from "react-router-dom";
import { toast } from "react-toastify";
import Alert from "~/app/components/Alert";
import Button from "~/app/components/Button";
import { ContentBox } from "~/app/components/ContentBox";
import toast from "~/app/components/Toast";
import Checkbox from "~/app/components/form/Checkbox";
import MnemonicInputs from "~/app/components/mnemonic/MnemonicInputs";
import api from "~/common/lib/api";
Expand Down
2 changes: 1 addition & 1 deletion src/app/screens/Accounts/ImportMnemonic/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { wordlist } from "@scure/bip39/wordlists/english";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate, useParams } from "react-router-dom";
import { toast } from "react-toastify";
import Alert from "~/app/components/Alert";
import Button from "~/app/components/Button";
import { ContentBox } from "~/app/components/ContentBox";
import toast from "~/app/components/Toast";
import MnemonicInputs from "~/app/components/mnemonic/MnemonicInputs";
import api from "~/common/lib/api";

Expand Down
Loading

0 comments on commit 25ce059

Please sign in to comment.