diff --git a/app/soapbox/actions/alerts.ts b/app/soapbox/actions/alerts.ts
index bbb492e42..8f200563a 100644
--- a/app/soapbox/actions/alerts.ts
+++ b/app/soapbox/actions/alerts.ts
@@ -5,6 +5,7 @@ import { httpErrorMessages } from 'soapbox/utils/errors';
import type { SnackbarActionSeverity } from './snackbar';
import type { AnyAction } from '@reduxjs/toolkit';
import type { AxiosError } from 'axios';
+import type { NotificationObject } from 'react-notification';
const messages = defineMessages({
unexpectedTitle: { id: 'alert.unexpected.title', defaultMessage: 'Oops!' },
@@ -17,7 +18,7 @@ export const ALERT_CLEAR = 'ALERT_CLEAR';
const noOp = () => { };
-function dismissAlert(alert: any) {
+function dismissAlert(alert: NotificationObject) {
return {
type: ALERT_DISMISS,
alert,
diff --git a/app/soapbox/features/ui/containers/notifications_container.js b/app/soapbox/features/ui/containers/notifications_container.tsx
similarity index 50%
rename from app/soapbox/features/ui/containers/notifications_container.js
rename to app/soapbox/features/ui/containers/notifications_container.tsx
index a735a3fdf..851cfdb3b 100644
--- a/app/soapbox/features/ui/containers/notifications_container.js
+++ b/app/soapbox/features/ui/containers/notifications_container.tsx
@@ -1,21 +1,15 @@
import React from 'react';
-import { injectIntl } from 'react-intl';
-import { NotificationStack } from 'react-notification';
-import { connect } from 'react-redux';
+import { useIntl } from 'react-intl';
+import { NotificationStack, NotificationObject, StyleFactoryFn } from 'react-notification';
import { Link } from 'react-router-dom';
import { Button } from 'soapbox/components/ui';
+import { useAppSelector, useAppDispatch } from 'soapbox/hooks';
import { dismissAlert } from '../../../actions/alerts';
import { getAlerts } from '../../../selectors';
-const CustomNotificationStack = (props) => (
-
-
-
-);
-
-const defaultBarStyleFactory = (index, style, notification) => {
+const defaultBarStyleFactory: StyleFactoryFn = (index, style, _notification) => {
return Object.assign(
{},
style,
@@ -23,14 +17,19 @@ const defaultBarStyleFactory = (index, style, notification) => {
);
};
-const mapStateToProps = (state, { intl }) => {
- const notifications = getAlerts(state);
+const SnackbarContainer: React.FC = () => {
+ const intl = useIntl();
+ const dispatch = useAppDispatch();
+
+ const notifications = useAppSelector(getAlerts);
notifications.forEach(notification => {
['title', 'message', 'actionLabel'].forEach(key => {
+ // @ts-ignore
const value = notification[key];
if (typeof value === 'object') {
+ // @ts-ignore
notification[key] = intl.formatMessage(value);
}
});
@@ -49,20 +48,21 @@ const mapStateToProps = (state, { intl }) => {
}
});
- return { notifications, linkComponent: Link };
-};
-
-const mapDispatchToProps = (dispatch) => {
- const onDismiss = alert => {
+ const onDismiss = (alert: NotificationObject) => {
dispatch(dismissAlert(alert));
};
- return {
- onDismiss,
- onClick: onDismiss,
- barStyleFactory: defaultBarStyleFactory,
- activeBarStyleFactory: defaultBarStyleFactory,
- };
+ return (
+
+
+
+ );
};
-export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(CustomNotificationStack));
+export default SnackbarContainer;
diff --git a/app/soapbox/reducers/alerts.ts b/app/soapbox/reducers/alerts.ts
index 6d495bb7f..57ac4904c 100644
--- a/app/soapbox/reducers/alerts.ts
+++ b/app/soapbox/reducers/alerts.ts
@@ -22,20 +22,20 @@ type PlainAlert = Record;
type Alert = ReturnType;
type State = ImmutableList;
-// Get next key based on last alert
+/** Get next key based on last alert. */
const getNextKey = (state: State): number => {
const last = state.last();
return last ? last.key + 1 : 0;
};
-// Import the alert
+/** Import the alert. */
const importAlert = (state: State, alert: PlainAlert): State => {
const key = getNextKey(state);
const record = AlertRecord({ ...alert, key });
return state.push(record);
};
-// Delete an alert by its key
+/** Delete an alert by its key. */
const deleteAlert = (state: State, alert: PlainAlert): State => {
return state.filterNot(item => item.key === alert.key);
};