Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2174: Replace unmaintained react-toast-notifications (and use one style for all toasts) #2836

Merged
merged 18 commits into from
Mar 3, 2022
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 0 additions & 27 deletions __mocks__/react-toast-notifications.js

This file was deleted.

23 changes: 0 additions & 23 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@
"react-shadow-root": "^6.1.0",
"react-spinners": "0.9.0",
"react-table": "^7.7.0",
"react-toast-notifications": "^2.4.4",
"react-transition-group": "^4.4.2",
"react-virtualized": "^9.22.3",
"react-virtualized-auto-sizer": "^1.0.6",
Expand Down
16 changes: 6 additions & 10 deletions src/auth/ScopeSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { StatusCodes } from "http-status-codes";
import { getLinkedApiClient } from "@/services/apiClient";
import { isAxiosError } from "@/errors";
import reportError from "@/telemetry/reportError";
import useNotifications from "@/hooks/useNotifications";
import notify from "@/utils/notify";
import ConnectedFieldTemplate from "@/components/form/ConnectedFieldTemplate";
import { useGetAuthQuery } from "@/services/api";

Expand Down Expand Up @@ -56,7 +56,6 @@ const ScopeSettings: React.VoidFunctionComponent<ScopeSettingsProps> = ({
title,
description,
}) => {
const notify = useNotifications();
const { refetch: refetchAuth } = useGetAuthQuery();

const submit = useCallback(
Expand All @@ -68,15 +67,14 @@ const ScopeSettings: React.VoidFunctionComponent<ScopeSettingsProps> = ({
await (await getLinkedApiClient()).patch("/api/settings/", values);
} catch (error) {
if (!isAxiosError(error)) {
notify.error("Error updating account alias", {
error,
});
notify.error({ message: "Error updating account alias", error });
Copy link
Contributor Author

@fregante fregante Feb 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API improvement: Either call it with a plain string or provide a regular Notification object.

Pros:

  • no awkward { error } wrap
  • simpler types
  • safer: no unknown as the first parameter of notify.error just to allow notify.error(new Error())

Cons:

  • 8 extra characters 😌 message: if you need to include the error

Copy link
Contributor

@twschiller twschiller Mar 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8 extra characters 😌 message: if you need to include the error

I'm not sure we have the budget for the extra storage

return;
}

switch (error.response.status) {
case StatusCodes.UNAUTHORIZED: {
notify.error("Could not authenticate with PixieBrix", {
notify.error({
message: "Could not authenticate with PixieBrix",
error,
});
return;
Expand All @@ -89,17 +87,15 @@ const ScopeSettings: React.VoidFunctionComponent<ScopeSettingsProps> = ({

default: {
reportError(error);
notify.error("Error updating account alias", {
error,
});
notify.error({ message: "Error updating account alias", error });
return;
}
}
}

refetchAuth();
},
[notify]
[]
);

return (
Expand Down
18 changes: 5 additions & 13 deletions src/background/contextMenus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ import browser, { Menus, Tabs } from "webextension-polyfill";
import { getErrorMessage, hasCancelRootCause } from "@/errors";
import reportError from "@/telemetry/reportError";
import { noop } from "lodash";
import {
handleMenuAction,
showNotification,
} from "@/contentScript/messenger/api";
import { handleMenuAction, notify } from "@/contentScript/messenger/api";
import { ensureContentScript } from "@/background/util";
import { reportEvent } from "@/telemetry/events";
import { UUID, IExtension, ResolvedExtension } from "@/core";
Expand Down Expand Up @@ -95,21 +92,16 @@ async function dispatchMenu(
extensionId: info.menuItemId.slice(MENU_PREFIX.length) as UUID,
args: info,
});
void showNotification(target, {
message: "Ran content menu item action",
type: "success",
});
notify.success(target, "Ran content menu item action");
} catch (error) {
if (hasCancelRootCause(error)) {
void showNotification(target, {
message: "The action was cancelled",
});
notify.info(target, "The action was cancelled");
} else {
const message = `Error handling context menu action: ${getErrorMessage(
error
)}`;
reportError(new Error(message));
void showNotification(target, { message, type: "error" });
reportError(error);
Copy link
Contributor Author

@fregante fregante Feb 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to report the original error here. The stack trace will point to this block anyway, but its origin will be better defined.

Here it's called explicitly because the messaging API does not automatically serialize errors, especially deep inside other objects.

notify.error(target, { message, reportError: false });
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/blocks/effects/alert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import { Effect } from "@/types";
import { BlockArg, Schema } from "@/core";
import { propertiesToSchema } from "@/validators/generic";
import { showNotification } from "@/contentScript/notify";
import { showNotification } from "@/utils/notify";

export class AlertEffect extends Effect {
constructor() {
Expand Down
2 changes: 1 addition & 1 deletion src/blocks/renderers/customForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import JsonSchemaForm from "@rjsf/bootstrap-4";
import { JsonObject } from "type-fest";
import { dataStore } from "@/background/messenger/api";
import reportError from "@/telemetry/reportError";
import { notifyResult } from "@/contentScript/notify";
import { notifyResult } from "@/utils/notify";

import custom from "@/blocks/renderers/customForm.css?loadAsUrl";
import BootstrapStylesheet from "./BootstrapStylesheet";
Expand Down
13 changes: 5 additions & 8 deletions src/components/documentBuilder/DocumentBuilder.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
Form as BootstrapForm,
Row,
} from "react-bootstrap";
import { ToastProvider } from "react-toast-notifications";
import DocumentEditor from "./edit/DocumentEditor";
import DocumentPreview from "./preview/DocumentPreview";
import { action } from "@storybook/addon-actions";
Expand Down Expand Up @@ -55,13 +54,11 @@ const DocumentBuilder: React.FC = () => {
/>
</Col>
<Col>
<ToastProvider>
<DocumentPreview
name="body"
activeElement={activeElement}
setActiveElement={setActiveElement}
/>
</ToastProvider>
<DocumentPreview
name="body"
activeElement={activeElement}
setActiveElement={setActiveElement}
/>
</Col>
</Row>
<Row className="mt-5">
Expand Down
5 changes: 1 addition & 4 deletions src/components/jsonTree/JsonTree.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import React from "react";
import { ComponentMeta, ComponentStory } from "@storybook/react";
import { ToastProvider } from "react-toast-notifications";
import JsonTree from "./JsonTree";

export default {
Expand All @@ -26,9 +25,7 @@ export default {
} as ComponentMeta<typeof JsonTree>;

const Template: ComponentStory<typeof JsonTree> = (args) => (
<ToastProvider>
<JsonTree {...args} />
</ToastProvider>
<JsonTree {...args} />
);

const exampleValues = {
Expand Down
11 changes: 3 additions & 8 deletions src/components/jsonTree/treeHooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,12 @@ import React, { useCallback } from "react";
import copy from "copy-to-clipboard";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCopy } from "@fortawesome/free-solid-svg-icons";
import { useToasts } from "react-toast-notifications";
import notify from "@/utils/notify";
import styles from "./JsonTree.module.scss";
import { Button } from "react-bootstrap";
import cx from "classnames";

export function useLabelRenderer() {
const { addToast } = useToasts();

// https://github.com/reduxjs/redux-devtools/blob/85b4b0fb04b1d6d95054d5073fa17fa61efc0df3/packages/redux-devtools-inspector-monitor/src/ActionPreview.tsx
return useCallback(
(
Expand All @@ -44,16 +42,13 @@ export function useLabelRenderer() {
onClick={(event) => {
copy([key, ...rest].reverse().join("."));
event.stopPropagation();
addToast("Copied property path to the clipboard", {
appearance: "info",
autoDismiss: true,
});
notify.info("Copied property path to the clipboard");
}}
>
<FontAwesomeIcon icon={faCopy} aria-hidden />
</Button>
</div>
),
[addToast]
[]
);
}
5 changes: 1 addition & 4 deletions src/components/logViewer/LogToolbar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import React from "react";
import { ComponentMeta, ComponentStory } from "@storybook/react";
import LogToolbar from "./LogToolbar";
import { ToastProvider } from "react-toast-notifications";
import { action } from "@storybook/addon-actions";

const promiseAction = (name: string) => {
Expand All @@ -42,9 +41,7 @@ const componentMeta: ComponentMeta<typeof LogToolbar> = {
};

const Template: ComponentStory<typeof LogToolbar> = (args) => (
<ToastProvider>
<LogToolbar {...args} />
</ToastProvider>
<LogToolbar {...args} />
);

export const Default = Template.bind({});
Expand Down
24 changes: 8 additions & 16 deletions src/components/logViewer/LogToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import type { MessageLevel } from "@/background/logging";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faSync, faTrash } from "@fortawesome/free-solid-svg-icons";
import React, { useCallback } from "react";
import { useToasts } from "react-toast-notifications";
import notify from "@/utils/notify";
import AsyncButton from "@/components/AsyncButton";
import Pagination from "@/components/pagination/Pagination";

Expand Down Expand Up @@ -48,30 +48,22 @@ const LogToolbar: React.FunctionComponent<{
// Don't support "trace" by default
levelOptions = ["debug", "info", "warn", "error"],
}) => {
const { addToast } = useToasts();

const onClear = () => {
try {
clear();
addToast("Cleared the log entries for this extension", {
appearance: "success",
autoDismiss: true,
});
} catch {
addToast("Error clearing log entries for extension", {
appearance: "error",
autoDismiss: true,
notify.success("Cleared the log entries for this extension");
} catch (error) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error was not reported, now it is.

notify.error({
message: "Error clearing log entries for extension",
error,
});
}
};

const onRefresh = useCallback(() => {
refresh();
addToast("Refreshed the log entries", {
appearance: "success",
autoDismiss: true,
});
}, [refresh, addToast]);
notify.success("Refreshed the log entries");
}, [refresh]);

return (
<div className="px-3 pt-2">
Expand Down
2 changes: 1 addition & 1 deletion src/contentScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { markReady, updateTabInfo } from "@/contentScript/context";
import { whoAmI, initTelemetry } from "@/background/messenger/api";
import { ENSURE_CONTENT_SCRIPT_READY } from "@/messaging/constants";
import { addListenerForUpdateSelectedElement } from "@/devTools/getSelectedElement";
import { initToaster } from "@/contentScript/notify";
import { initToaster } from "@/utils/notify";
import { isConnectionError } from "@/errors";
import { showConnectionLost } from "@/contentScript/connection";

Expand Down
5 changes: 2 additions & 3 deletions src/contentScript/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { hideNotification, showNotification } from "@/contentScript/notify";
import notify, { hideNotification } from "@/utils/notify";

const id = "connection-lost";

export function showConnectionLost(): void {
showNotification({
notify.error({
id,
message: "Connection to PixieBrix lost. Please reload the page",
type: "error",
duration: Number.POSITIVE_INFINITY,
});
}
Expand Down
7 changes: 6 additions & 1 deletion src/contentScript/messenger/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,16 @@ export const disableOverlay = getMethod("DISABLE_OVERLAY");
export const getInstalledExtensionPointIds = getMethod("INSTALLED_EXTENSIONS");
export const checkAvailable = getMethod("CHECK_AVAILABLE");
export const handleNavigate = getNotifier("HANDLE_NAVIGATE");
export const showNotification = getMethod("SHOW_NOTIFICATION");
export const runBrick = getMethod("RUN_BRICK");
export const cancelSelect = getMethod("CANCEL_SELECT_ELEMENT");
export const selectElement = getMethod("SELECT_ELEMENT");

export const runRendererPipeline = getMethod("RUN_RENDERER_PIPELINE");
export const runEffectPipeline = getMethod("RUN_EFFECT_PIPELINE");
export const runMapArgs = getMethod("RUN_MAP_ARGS");

export const notify = {
info: getNotifier("NOTIFY_INFO"),
error: getNotifier("NOTIFY_ERROR"),
success: getNotifier("NOTIFY_SUCCESS"),
};
Loading