From b7d0b4abe84af60489dd5fcc771672a56999f2e7 Mon Sep 17 00:00:00 2001 From: Chewbacca Date: Tue, 20 Dec 2022 10:47:46 -0500 Subject: [PATCH] Convert 'success' usage to Toast --- app/soapbox/actions/aliases.ts | 10 ++++---- app/soapbox/actions/auth.ts | 3 ++- app/soapbox/actions/compose.ts | 6 ++++- app/soapbox/actions/events.ts | 23 ++++++++++++------ app/soapbox/actions/export-data.ts | 8 +++---- app/soapbox/actions/filters.ts | 6 ++--- app/soapbox/actions/import-data.ts | 8 +++---- app/soapbox/actions/interactions.ts | 9 ++++--- app/soapbox/actions/moderation.tsx | 10 ++++---- app/soapbox/actions/security.ts | 4 ++-- app/soapbox/actions/settings.ts | 4 ++-- app/soapbox/containers/soapbox.tsx | 3 +++ .../features/account/components/header.tsx | 5 ++-- .../components/registration-mode-picker.tsx | 4 ++-- .../features/admin/components/report.tsx | 4 ++-- .../admin/components/unapproved-account.tsx | 3 ++- app/soapbox/features/delete-account/index.tsx | 3 ++- .../developers/developers-challenge.tsx | 3 ++- .../features/developers/developers-menu.tsx | 21 ++++++++++++++-- app/soapbox/features/edit-email/index.tsx | 3 ++- app/soapbox/features/edit-password/index.tsx | 3 ++- app/soapbox/features/edit-profile/index.tsx | 3 ++- .../features/email-confirmation/index.tsx | 7 ++---- app/soapbox/features/migration/index.tsx | 3 ++- .../security/mfa/disable-otp-form.tsx | 3 ++- .../security/mfa/otp-confirm-form.tsx | 3 ++- app/soapbox/features/soapbox-config/index.tsx | 4 ++-- app/soapbox/features/theme-editor/index.tsx | 8 +++---- .../account-moderation-modal.tsx | 8 +++---- .../staff-role-picker.tsx | 4 ++-- .../modals/edit-federation-modal.tsx | 4 ++-- .../ui/components/modals/verify-sms-modal.tsx | 7 +++--- .../ui/components/subscription-button.tsx | 5 ++-- .../features/verification/email-passthru.tsx | 3 ++- .../features/verification/registration.tsx | 7 +++--- .../verification/steps/email-verification.tsx | 10 +++----- .../verification/steps/sms-verification.tsx | 24 ++++++------------- app/soapbox/queries/accounts.ts | 6 ++--- app/soapbox/queries/chats.ts | 8 +++---- 39 files changed, 145 insertions(+), 115 deletions(-) diff --git a/app/soapbox/actions/aliases.ts b/app/soapbox/actions/aliases.ts index 8361e31ad..dc660d3ea 100644 --- a/app/soapbox/actions/aliases.ts +++ b/app/soapbox/actions/aliases.ts @@ -1,5 +1,6 @@ import { defineMessages } from 'react-intl'; +import toast from 'soapbox/toast'; import { isLoggedIn } from 'soapbox/utils/auth'; import { getFeatures } from 'soapbox/utils/features'; @@ -8,7 +9,6 @@ import api from '../api'; import { showAlertForError } from './alerts'; import { importFetchedAccounts } from './importer'; import { patchMeSuccess } from './me'; -import snackbar from './snackbar'; import type { AxiosError } from 'axios'; import type { AppDispatch, RootState } from 'soapbox/store'; @@ -114,7 +114,7 @@ const addToAliases = (account: Account) => api(getState).patch('/api/v1/accounts/update_credentials', { also_known_as: [...alsoKnownAs, account.pleroma.get('ap_id')] }) .then((response => { - dispatch(snackbar.success(messages.createSuccess)); + toast.success(messages.createSuccess); dispatch(addToAliasesSuccess); dispatch(patchMeSuccess(response.data)); })) @@ -129,7 +129,7 @@ const addToAliases = (account: Account) => alias: account.acct, }) .then(() => { - dispatch(snackbar.success(messages.createSuccess)); + toast.success(messages.createSuccess); dispatch(addToAliasesSuccess); dispatch(fetchAliases); }) @@ -165,7 +165,7 @@ const removeFromAliases = (account: string) => api(getState).patch('/api/v1/accounts/update_credentials', { also_known_as: alsoKnownAs.filter((id: string) => id !== account) }) .then(response => { - dispatch(snackbar.success(messages.removeSuccess)); + toast.success(messages.removeSuccess); dispatch(removeFromAliasesSuccess); dispatch(patchMeSuccess(response.data)); }) @@ -182,7 +182,7 @@ const removeFromAliases = (account: string) => }, }) .then(response => { - dispatch(snackbar.success(messages.removeSuccess)); + toast.success(messages.removeSuccess); dispatch(removeFromAliasesSuccess); dispatch(fetchAliases); }) diff --git a/app/soapbox/actions/auth.ts b/app/soapbox/actions/auth.ts index 39a6c7c81..1469dfd65 100644 --- a/app/soapbox/actions/auth.ts +++ b/app/soapbox/actions/auth.ts @@ -18,6 +18,7 @@ import snackbar from 'soapbox/actions/snackbar'; import { custom } from 'soapbox/custom'; import { queryClient } from 'soapbox/queries/client'; import KVStore from 'soapbox/storage/kv-store'; +import toast from 'soapbox/toast'; import { getLoggedInAccount, parseBaseURL } from 'soapbox/utils/auth'; import sourceCode from 'soapbox/utils/code'; import { getFeatures } from 'soapbox/utils/features'; @@ -246,7 +247,7 @@ export const logOut = () => dispatch({ type: AUTH_LOGGED_OUT, account, standalone }); - return dispatch(snackbar.success(messages.loggedOut)); + toast.success(messages.loggedOut); }); }; diff --git a/app/soapbox/actions/compose.ts b/app/soapbox/actions/compose.ts index 4519425e1..5bd371e9e 100644 --- a/app/soapbox/actions/compose.ts +++ b/app/soapbox/actions/compose.ts @@ -7,6 +7,7 @@ import snackbar from 'soapbox/actions/snackbar'; import api from 'soapbox/api'; import { search as emojiSearch } from 'soapbox/features/emoji/emoji-mart-search-light'; import { tagHistory } from 'soapbox/settings'; +import toast from 'soapbox/toast'; import { isLoggedIn } from 'soapbox/utils/auth'; import { getFeatures, parseVersion } from 'soapbox/utils/features'; import { formatBytes, getVideoDuration } from 'soapbox/utils/media'; @@ -211,7 +212,10 @@ const handleComposeSubmit = (dispatch: AppDispatch, getState: () => RootState, c dispatch(insertIntoTagHistory(composeId, data.tags || [], status)); dispatch(submitComposeSuccess(composeId, { ...data })); - dispatch(snackbar.success(edit ? messages.editSuccess : messages.success, messages.view, `/@${data.account.acct}/posts/${data.id}`)); + toast.success(edit ? messages.editSuccess : messages.success, { + actionLabel: messages.view, + actionLink: `/@${data.account.acct}/posts/${data.id}`, + }); }; const needsDescriptions = (state: RootState, composeId: string) => { diff --git a/app/soapbox/actions/events.ts b/app/soapbox/actions/events.ts index 55bf6eec3..45c715917 100644 --- a/app/soapbox/actions/events.ts +++ b/app/soapbox/actions/events.ts @@ -1,6 +1,7 @@ import { defineMessages, IntlShape } from 'react-intl'; import api, { getLinks } from 'soapbox/api'; +import toast from 'soapbox/toast'; import { formatBytes } from 'soapbox/utils/media'; import resizeImage from 'soapbox/utils/resize-image'; @@ -264,7 +265,13 @@ const submitEvent = () => dispatch(closeModal('COMPOSE_EVENT')); dispatch(importFetchedStatus(data)); dispatch(submitEventSuccess(data)); - dispatch(snackbar.success(id ? messages.editSuccess : messages.success, messages.view, `/@${data.account.acct}/events/${data.id}`)); + toast.success( + id ? messages.editSuccess : messages.success, + { + actionLabel: messages.view, + actionLink: `/@${data.account.acct}/events/${data.id}`, + }, + ); }).catch(function(error) { dispatch(submitEventFail(error)); }); @@ -299,11 +306,13 @@ const joinEvent = (id: string, participationMessage?: string) => }).then(({ data }) => { dispatch(importFetchedStatus(data)); dispatch(joinEventSuccess(data)); - dispatch(snackbar.success( + toast.success( data.pleroma.event?.join_state === 'pending' ? messages.joinRequestSuccess : messages.joinSuccess, - messages.view, - `/@${data.account.acct}/events/${data.id}`, - )); + { + actionLabel: messages.view, + actionLink: `/@${data.account.acct}/events/${data.id}`, + }, + ); }).catch(function(error) { dispatch(joinEventFail(error, status, status?.event?.join_state || null)); }); @@ -504,7 +513,7 @@ const authorizeEventParticipationRequest = (id: string, accountId: string) => .post(`/api/v1/pleroma/events/${id}/participation_requests/${accountId}/authorize`) .then(() => { dispatch(authorizeEventParticipationRequestSuccess(id, accountId)); - dispatch(snackbar.success(messages.authorized)); + toast.success(messages.authorized); }) .catch(error => dispatch(authorizeEventParticipationRequestFail(id, accountId, error))); }; @@ -536,7 +545,7 @@ const rejectEventParticipationRequest = (id: string, accountId: string) => .post(`/api/v1/pleroma/events/${id}/participation_requests/${accountId}/reject`) .then(() => { dispatch(rejectEventParticipationRequestSuccess(id, accountId)); - dispatch(snackbar.success(messages.rejected)); + toast.success(messages.rejected); }) .catch(error => dispatch(rejectEventParticipationRequestFail(id, accountId, error))); }; diff --git a/app/soapbox/actions/export-data.ts b/app/soapbox/actions/export-data.ts index b558c9e6e..cbfaef82e 100644 --- a/app/soapbox/actions/export-data.ts +++ b/app/soapbox/actions/export-data.ts @@ -1,8 +1,8 @@ import { defineMessages } from 'react-intl'; -import snackbar from 'soapbox/actions/snackbar'; import api, { getLinks } from 'soapbox/api'; import { normalizeAccount } from 'soapbox/normalizers'; +import toast from 'soapbox/toast'; import type { SnackbarAction } from './snackbar'; import type { AxiosResponse } from 'axios'; @@ -75,7 +75,7 @@ export const exportFollows = () => (dispatch: React.Dispatch, followings.unshift('Account address,Show boosts'); fileExport(followings.join('\n'), 'export_followings.csv'); - dispatch(snackbar.success(messages.followersSuccess)); + toast.success(messages.followersSuccess); dispatch({ type: EXPORT_FOLLOWS_SUCCESS }); }).catch(error => { dispatch({ type: EXPORT_FOLLOWS_FAIL, error }); @@ -90,7 +90,7 @@ export const exportBlocks = () => (dispatch: React.Dispatch, .then((blocks) => { fileExport(blocks.join('\n'), 'export_block.csv'); - dispatch(snackbar.success(messages.blocksSuccess)); + toast.success(messages.blocksSuccess); dispatch({ type: EXPORT_BLOCKS_SUCCESS }); }).catch(error => { dispatch({ type: EXPORT_BLOCKS_FAIL, error }); @@ -105,7 +105,7 @@ export const exportMutes = () => (dispatch: React.Dispatch, g .then((mutes) => { fileExport(mutes.join('\n'), 'export_mutes.csv'); - dispatch(snackbar.success(messages.mutesSuccess)); + toast.success(messages.mutesSuccess); dispatch({ type: EXPORT_MUTES_SUCCESS }); }).catch(error => { dispatch({ type: EXPORT_MUTES_FAIL, error }); diff --git a/app/soapbox/actions/filters.ts b/app/soapbox/actions/filters.ts index c0f79c6b8..7e663f88d 100644 --- a/app/soapbox/actions/filters.ts +++ b/app/soapbox/actions/filters.ts @@ -1,6 +1,6 @@ import { defineMessages } from 'react-intl'; -import snackbar from 'soapbox/actions/snackbar'; +import toast from 'soapbox/toast'; import { isLoggedIn } from 'soapbox/utils/auth'; import { getFeatures } from 'soapbox/utils/features'; @@ -66,7 +66,7 @@ const createFilter = (phrase: string, expires_at: string, context: Array expires_at, }).then(response => { dispatch({ type: FILTERS_CREATE_SUCCESS, filter: response.data }); - dispatch(snackbar.success(messages.added)); + toast.success(messages.added); }).catch(error => { dispatch({ type: FILTERS_CREATE_FAIL, error }); }); @@ -77,7 +77,7 @@ const deleteFilter = (id: string) => dispatch({ type: FILTERS_DELETE_REQUEST }); return api(getState).delete(`/api/v1/filters/${id}`).then(response => { dispatch({ type: FILTERS_DELETE_SUCCESS, filter: response.data }); - dispatch(snackbar.success(messages.removed)); + toast.success(messages.removed); }).catch(error => { dispatch({ type: FILTERS_DELETE_FAIL, error }); }); diff --git a/app/soapbox/actions/import-data.ts b/app/soapbox/actions/import-data.ts index 43de9f85c..47e24caa5 100644 --- a/app/soapbox/actions/import-data.ts +++ b/app/soapbox/actions/import-data.ts @@ -1,6 +1,6 @@ import { defineMessages } from 'react-intl'; -import snackbar from 'soapbox/actions/snackbar'; +import toast from 'soapbox/toast'; import api from '../api'; @@ -45,7 +45,7 @@ export const importFollows = (params: FormData) => return api(getState) .post('/api/pleroma/follow_import', params) .then(response => { - dispatch(snackbar.success(messages.followersSuccess)); + toast.success(messages.followersSuccess); dispatch({ type: IMPORT_FOLLOWS_SUCCESS, config: response.data }); }).catch(error => { dispatch({ type: IMPORT_FOLLOWS_FAIL, error }); @@ -58,7 +58,7 @@ export const importBlocks = (params: FormData) => return api(getState) .post('/api/pleroma/blocks_import', params) .then(response => { - dispatch(snackbar.success(messages.blocksSuccess)); + toast.success(messages.blocksSuccess); dispatch({ type: IMPORT_BLOCKS_SUCCESS, config: response.data }); }).catch(error => { dispatch({ type: IMPORT_BLOCKS_FAIL, error }); @@ -71,7 +71,7 @@ export const importMutes = (params: FormData) => return api(getState) .post('/api/pleroma/mutes_import', params) .then(response => { - dispatch(snackbar.success(messages.mutesSuccess)); + toast.success(messages.mutesSuccess); dispatch({ type: IMPORT_MUTES_SUCCESS, config: response.data }); }).catch(error => { dispatch({ type: IMPORT_MUTES_FAIL, error }); diff --git a/app/soapbox/actions/interactions.ts b/app/soapbox/actions/interactions.ts index cb23f3dae..554844609 100644 --- a/app/soapbox/actions/interactions.ts +++ b/app/soapbox/actions/interactions.ts @@ -1,6 +1,6 @@ import { defineMessages } from 'react-intl'; -import snackbar from 'soapbox/actions/snackbar'; +import toast from 'soapbox/toast'; import { isLoggedIn } from 'soapbox/utils/auth'; import api from '../api'; @@ -222,7 +222,10 @@ const bookmark = (status: StatusEntity) => api(getState).post(`/api/v1/statuses/${status.get('id')}/bookmark`).then(function(response) { dispatch(importFetchedStatus(response.data)); dispatch(bookmarkSuccess(status, response.data)); - dispatch(snackbar.success(messages.bookmarkAdded, messages.view, '/bookmarks')); + toast.success(messages.bookmarkAdded, { + actionLabel: messages.view, + actionLink: '/bookmarks', + }); }).catch(function(error) { dispatch(bookmarkFail(status, error)); }); @@ -235,7 +238,7 @@ const unbookmark = (status: StatusEntity) => api(getState).post(`/api/v1/statuses/${status.get('id')}/unbookmark`).then(response => { dispatch(importFetchedStatus(response.data)); dispatch(unbookmarkSuccess(status, response.data)); - dispatch(snackbar.success(messages.bookmarkRemoved)); + toast.success(messages.bookmarkRemoved); }).catch(error => { dispatch(unbookmarkFail(status, error)); }); diff --git a/app/soapbox/actions/moderation.tsx b/app/soapbox/actions/moderation.tsx index 1791500b5..5b0a4a5f2 100644 --- a/app/soapbox/actions/moderation.tsx +++ b/app/soapbox/actions/moderation.tsx @@ -4,10 +4,10 @@ import { defineMessages, IntlShape } from 'react-intl'; import { fetchAccountByUsername } from 'soapbox/actions/accounts'; import { deactivateUsers, deleteUsers, deleteStatus, toggleStatusSensitivity } from 'soapbox/actions/admin'; import { openModal } from 'soapbox/actions/modals'; -import snackbar from 'soapbox/actions/snackbar'; import OutlineBox from 'soapbox/components/outline-box'; import { Stack, Text } from 'soapbox/components/ui'; import AccountContainer from 'soapbox/containers/account-container'; +import toast from 'soapbox/toast'; import { isLocal } from 'soapbox/utils/accounts'; import type { AppDispatch, RootState } from 'soapbox/store'; @@ -65,7 +65,7 @@ const deactivateUserModal = (intl: IntlShape, accountId: string, afterConfirm = onConfirm: () => { dispatch(deactivateUsers([accountId])).then(() => { const message = intl.formatMessage(messages.userDeactivated, { acct }); - dispatch(snackbar.success(message)); + toast.success(message); afterConfirm(); }).catch(() => {}); }, @@ -105,7 +105,7 @@ const deleteUserModal = (intl: IntlShape, accountId: string, afterConfirm = () = dispatch(deleteUsers([accountId])).then(() => { const message = intl.formatMessage(messages.userDeleted, { acct }); dispatch(fetchAccountByUsername(acct)); - dispatch(snackbar.success(message)); + toast.success(message); afterConfirm(); }).catch(() => {}); }, @@ -147,7 +147,7 @@ const toggleStatusSensitivityModal = (intl: IntlShape, statusId: string, sensiti onConfirm: () => { dispatch(toggleStatusSensitivity(statusId, sensitive)).then(() => { const message = intl.formatMessage(sensitive === false ? messages.statusMarkedSensitive : messages.statusMarkedNotSensitive, { acct }); - dispatch(snackbar.success(message)); + toast.success(message); }).catch(() => {}); afterConfirm(); }, @@ -168,7 +168,7 @@ const deleteStatusModal = (intl: IntlShape, statusId: string, afterConfirm = () onConfirm: () => { dispatch(deleteStatus(statusId)).then(() => { const message = intl.formatMessage(messages.statusDeleted, { acct }); - dispatch(snackbar.success(message)); + toast.success(message); }).catch(() => {}); afterConfirm(); }, diff --git a/app/soapbox/actions/security.ts b/app/soapbox/actions/security.ts index 196e54dcb..48304aa23 100644 --- a/app/soapbox/actions/security.ts +++ b/app/soapbox/actions/security.ts @@ -4,7 +4,7 @@ * @see module:soapbox/actions/auth */ -import snackbar from 'soapbox/actions/snackbar'; +import toast from 'soapbox/toast'; import { getLoggedInAccount } from 'soapbox/utils/auth'; import { parseVersion, TRUTHSOCIAL } from 'soapbox/utils/features'; import { normalizeUsername } from 'soapbox/utils/input'; @@ -152,7 +152,7 @@ const deleteAccount = (password: string) => if (response.data.error) throw response.data.error; // This endpoint returns HTTP 200 even on failure dispatch({ type: DELETE_ACCOUNT_SUCCESS, response }); dispatch({ type: AUTH_LOGGED_OUT, account }); - dispatch(snackbar.success(messages.loggedOut)); + toast.success(messages.loggedOut); }).catch(error => { dispatch({ type: DELETE_ACCOUNT_FAIL, error, skipAlert: true }); throw error; diff --git a/app/soapbox/actions/settings.ts b/app/soapbox/actions/settings.ts index 44a22f666..9c2399ace 100644 --- a/app/soapbox/actions/settings.ts +++ b/app/soapbox/actions/settings.ts @@ -4,10 +4,10 @@ import { createSelector } from 'reselect'; import { v4 as uuid } from 'uuid'; import { patchMe } from 'soapbox/actions/me'; +import toast from 'soapbox/toast'; import { isLoggedIn } from 'soapbox/utils/auth'; import { showAlertForError } from './alerts'; -import snackbar from './snackbar'; import type { AppDispatch, RootState } from 'soapbox/store'; @@ -222,7 +222,7 @@ const saveSettingsImmediate = (opts?: SettingOpts) => dispatch({ type: SETTING_SAVE }); if (opts?.showAlert) { - dispatch(snackbar.success(messages.saveSuccess)); + toast.success(messages.saveSuccess); } }).catch(error => { dispatch(showAlertForError(error)); diff --git a/app/soapbox/containers/soapbox.tsx b/app/soapbox/containers/soapbox.tsx index 2beaa516c..cccfae997 100644 --- a/app/soapbox/containers/soapbox.tsx +++ b/app/soapbox/containers/soapbox.tsx @@ -3,12 +3,14 @@ import { QueryClientProvider } from '@tanstack/react-query'; import classNames from 'clsx'; import React, { useState, useEffect } from 'react'; +import { Toaster } from 'react-hot-toast'; import { IntlProvider } from 'react-intl'; import { Provider } from 'react-redux'; import { BrowserRouter, Switch, Redirect, Route } from 'react-router-dom'; // @ts-ignore: it doesn't have types import { ScrollContext } from 'react-router-scroll-4'; + import { loadInstance } from 'soapbox/actions/instance'; import { fetchMe } from 'soapbox/actions/me'; import { loadSoapboxConfig, getSoapboxConfig } from 'soapbox/actions/soapbox'; @@ -194,6 +196,7 @@ const SoapboxMount = () => { + diff --git a/app/soapbox/features/account/components/header.tsx b/app/soapbox/features/account/components/header.tsx index e269b1668..041d38bf6 100644 --- a/app/soapbox/features/account/components/header.tsx +++ b/app/soapbox/features/account/components/header.tsx @@ -27,6 +27,7 @@ import { useAppDispatch, useFeatures, useOwnAccount } from 'soapbox/hooks'; import { normalizeAttachment } from 'soapbox/normalizers'; import { ChatKeys, useChats } from 'soapbox/queries/chats'; import { queryClient } from 'soapbox/queries/client'; +import toast from 'soapbox/toast'; import { Account } from 'soapbox/types/entities'; import { isDefaultHeader, isRemote } from 'soapbox/utils/accounts'; @@ -158,11 +159,11 @@ const Header: React.FC = ({ account }) => { const onEndorseToggle = () => { if (account.relationship?.endorsed) { dispatch(unpinAccount(account.id)) - .then(() => dispatch(snackbar.success(intl.formatMessage(messages.userUnendorsed, { acct: account.acct })))) + .then(() => toast.success(intl.formatMessage(messages.userUnendorsed, { acct: account.acct }))) .catch(() => { }); } else { dispatch(pinAccount(account.id)) - .then(() => dispatch(snackbar.success(intl.formatMessage(messages.userEndorsed, { acct: account.acct })))) + .then(() => toast.success(intl.formatMessage(messages.userEndorsed, { acct: account.acct }))) .catch(() => { }); } }; diff --git a/app/soapbox/features/admin/components/registration-mode-picker.tsx b/app/soapbox/features/admin/components/registration-mode-picker.tsx index eab7f2f94..eea8f944b 100644 --- a/app/soapbox/features/admin/components/registration-mode-picker.tsx +++ b/app/soapbox/features/admin/components/registration-mode-picker.tsx @@ -2,9 +2,9 @@ import React from 'react'; import { useIntl, defineMessages, FormattedMessage } from 'react-intl'; import { updateConfig } from 'soapbox/actions/admin'; -import snackbar from 'soapbox/actions/snackbar'; import { RadioGroup, RadioItem } from 'soapbox/components/radio'; import { useAppDispatch, useInstance } from 'soapbox/hooks'; +import toast from 'soapbox/toast'; import type { Instance } from 'soapbox/types/entities'; @@ -44,7 +44,7 @@ const RegistrationModePicker: React.FC = () => { const onChange: React.ChangeEventHandler = e => { const config = generateConfig(e.target.value as RegistrationMode); dispatch(updateConfig(config)).then(() => { - dispatch(snackbar.success(intl.formatMessage(messages.saved))); + toast.success(intl.formatMessage(messages.saved)); }).catch(() => {}); }; diff --git a/app/soapbox/features/admin/components/report.tsx b/app/soapbox/features/admin/components/report.tsx index 3bf550419..c316e2c45 100644 --- a/app/soapbox/features/admin/components/report.tsx +++ b/app/soapbox/features/admin/components/report.tsx @@ -4,13 +4,13 @@ import { Link } from 'react-router-dom'; import { closeReports } from 'soapbox/actions/admin'; import { deactivateUserModal, deleteUserModal } from 'soapbox/actions/moderation'; -import snackbar from 'soapbox/actions/snackbar'; import Avatar from 'soapbox/components/avatar'; import HoverRefWrapper from 'soapbox/components/hover-ref-wrapper'; import { Accordion, Button, Stack, HStack, Text } from 'soapbox/components/ui'; import DropdownMenu from 'soapbox/containers/dropdown-menu-container'; import { useAppDispatch, useAppSelector } from 'soapbox/hooks'; import { makeGetReport } from 'soapbox/selectors'; +import toast from 'soapbox/toast'; import ReportStatus from './report-status'; @@ -58,7 +58,7 @@ const Report: React.FC = ({ id }) => { const handleCloseReport = () => { dispatch(closeReports([report.id])).then(() => { const message = intl.formatMessage(messages.reportClosed, { name: targetAccount.username as string }); - dispatch(snackbar.success(message)); + toast.success(message); }).catch(() => {}); }; diff --git a/app/soapbox/features/admin/components/unapproved-account.tsx b/app/soapbox/features/admin/components/unapproved-account.tsx index 514fcb370..9059eb817 100644 --- a/app/soapbox/features/admin/components/unapproved-account.tsx +++ b/app/soapbox/features/admin/components/unapproved-account.tsx @@ -7,6 +7,7 @@ import snackbar from 'soapbox/actions/snackbar'; import { Stack, HStack, Text, IconButton } from 'soapbox/components/ui'; import { useAppSelector, useAppDispatch } from 'soapbox/hooks'; import { makeGetAccount } from 'soapbox/selectors'; +import toast from 'soapbox/toast'; const messages = defineMessages({ approved: { id: 'admin.awaiting_approval.approved_message', defaultMessage: '{acct} was approved!' }, @@ -32,7 +33,7 @@ const UnapprovedAccount: React.FC = ({ accountId }) => { dispatch(approveUsers([account.id])) .then(() => { const message = intl.formatMessage(messages.approved, { acct: `@${account.acct}` }); - dispatch(snackbar.success(message)); + toast.success(message); }) .catch(() => {}); }; diff --git a/app/soapbox/features/delete-account/index.tsx b/app/soapbox/features/delete-account/index.tsx index 9bafff592..c22bed5f7 100644 --- a/app/soapbox/features/delete-account/index.tsx +++ b/app/soapbox/features/delete-account/index.tsx @@ -5,6 +5,7 @@ import { deleteAccount } from 'soapbox/actions/security'; import snackbar from 'soapbox/actions/snackbar'; import { Button, Card, CardBody, CardHeader, CardTitle, Form, FormActions, FormGroup, Input, Stack, Text } from 'soapbox/components/ui'; import { useAppDispatch, useFeatures } from 'soapbox/hooks'; +import toast from 'soapbox/toast'; const messages = defineMessages({ passwordFieldLabel: { id: 'security.fields.password.label', defaultMessage: 'Password' }, @@ -34,7 +35,7 @@ const DeleteAccount = () => { setLoading(true); dispatch(deleteAccount(password)).then(() => { setPassword(''); - dispatch(snackbar.success(intl.formatMessage(messages.deleteAccountSuccess))); + toast.success(intl.formatMessage(messages.deleteAccountSuccess)); }).finally(() => { setLoading(false); }).catch(() => { diff --git a/app/soapbox/features/developers/developers-challenge.tsx b/app/soapbox/features/developers/developers-challenge.tsx index 25fafd76a..a084069ad 100644 --- a/app/soapbox/features/developers/developers-challenge.tsx +++ b/app/soapbox/features/developers/developers-challenge.tsx @@ -5,6 +5,7 @@ import { useDispatch } from 'react-redux'; import { changeSettingImmediate } from 'soapbox/actions/settings'; import snackbar from 'soapbox/actions/snackbar'; import { Column, Button, Form, FormActions, FormGroup, Input, Text } from 'soapbox/components/ui'; +import toast from 'soapbox/toast'; const messages = defineMessages({ heading: { id: 'column.developers', defaultMessage: 'Developers' }, @@ -27,7 +28,7 @@ const DevelopersChallenge = () => { const handleSubmit = () => { if (answer === 'boxsoap') { dispatch(changeSettingImmediate(['isDeveloper'], true)); - dispatch(snackbar.success(intl.formatMessage(messages.success))); + toast.success(intl.formatMessage(messages.success)); } else { dispatch(snackbar.error(intl.formatMessage(messages.fail))); } diff --git a/app/soapbox/features/developers/developers-menu.tsx b/app/soapbox/features/developers/developers-menu.tsx index 2db25d527..f383f3b04 100644 --- a/app/soapbox/features/developers/developers-menu.tsx +++ b/app/soapbox/features/developers/developers-menu.tsx @@ -4,9 +4,9 @@ import { useDispatch } from 'react-redux'; import { Link, useHistory } from 'react-router-dom'; import { changeSettingImmediate } from 'soapbox/actions/settings'; -import snackbar from 'soapbox/actions/snackbar'; import { Column, Text } from 'soapbox/components/ui'; import SvgIcon from 'soapbox/components/ui/icon/svg-icon'; +import toast from 'soapbox/toast'; import sourceCode from 'soapbox/utils/code'; const messages = defineMessages({ @@ -39,10 +39,19 @@ const Developers: React.FC = () => { e.preventDefault(); dispatch(changeSettingImmediate(['isDeveloper'], false)); - dispatch(snackbar.success(intl.formatMessage(messages.leave))); + toast.success(intl.formatMessage(messages.leave)); history.push('/'); }; + const showSnackbar = (event: React.MouseEvent) => { + event.preventDefault(); + + toast.success('Hello world!', { + action: () => alert('hi'), + actionLabel: 'Click me', + }); + }; + return ( <> @@ -102,6 +111,14 @@ const Developers: React.FC = () => { + + + + + + + + diff --git a/app/soapbox/features/edit-email/index.tsx b/app/soapbox/features/edit-email/index.tsx index 6d77fd68f..479d9c90e 100644 --- a/app/soapbox/features/edit-email/index.tsx +++ b/app/soapbox/features/edit-email/index.tsx @@ -5,6 +5,7 @@ import { changeEmail } from 'soapbox/actions/security'; import snackbar from 'soapbox/actions/snackbar'; import { Button, Card, CardBody, CardHeader, CardTitle, Column, Form, FormActions, FormGroup, Input } from 'soapbox/components/ui'; import { useAppDispatch } from 'soapbox/hooks'; +import toast from 'soapbox/toast'; const messages = defineMessages({ header: { id: 'edit_email.header', defaultMessage: 'Change Email' }, @@ -38,7 +39,7 @@ const EditEmail = () => { setLoading(true); dispatch(changeEmail(email, password)).then(() => { setState(initialState); - dispatch(snackbar.success(intl.formatMessage(messages.updateEmailSuccess))); + toast.success(intl.formatMessage(messages.updateEmailSuccess)); }).finally(() => { setLoading(false); }).catch(() => { diff --git a/app/soapbox/features/edit-password/index.tsx b/app/soapbox/features/edit-password/index.tsx index ecb2d6bb1..e90cf9f1c 100644 --- a/app/soapbox/features/edit-password/index.tsx +++ b/app/soapbox/features/edit-password/index.tsx @@ -5,6 +5,7 @@ import { changePassword } from 'soapbox/actions/security'; import snackbar from 'soapbox/actions/snackbar'; import { Button, Card, CardBody, CardHeader, CardTitle, Column, Form, FormActions, FormGroup, Input } from 'soapbox/components/ui'; import { useAppDispatch, useFeatures } from 'soapbox/hooks'; +import toast from 'soapbox/toast'; import PasswordIndicator from '../verification/components/password-indicator'; @@ -44,7 +45,7 @@ const EditPassword = () => { setLoading(true); dispatch(changePassword(currentPassword, newPassword, newPasswordConfirmation)).then(() => { resetState(); - dispatch(snackbar.success(intl.formatMessage(messages.updatePasswordSuccess))); + toast.success(intl.formatMessage(messages.updatePasswordSuccess)); }).finally(() => { setLoading(false); diff --git a/app/soapbox/features/edit-profile/index.tsx b/app/soapbox/features/edit-profile/index.tsx index d1624ddf5..80c0c28a4 100644 --- a/app/soapbox/features/edit-profile/index.tsx +++ b/app/soapbox/features/edit-profile/index.tsx @@ -21,6 +21,7 @@ import { } from 'soapbox/components/ui'; import { useAppDispatch, useOwnAccount, useFeatures, useInstance } from 'soapbox/hooks'; import { normalizeAccount } from 'soapbox/normalizers'; +import toast from 'soapbox/toast'; import resizeImage from 'soapbox/utils/resize-image'; import ProfilePreview from './components/profile-preview'; @@ -217,7 +218,7 @@ const EditProfile: React.FC = () => { Promise.all(promises).then(() => { setLoading(false); - dispatch(snackbar.success(intl.formatMessage(messages.success))); + toast.success(intl.formatMessage(messages.success)); }).catch(() => { setLoading(false); dispatch(snackbar.error(intl.formatMessage(messages.error))); diff --git a/app/soapbox/features/email-confirmation/index.tsx b/app/soapbox/features/email-confirmation/index.tsx index 45d18444e..99c908640 100644 --- a/app/soapbox/features/email-confirmation/index.tsx +++ b/app/soapbox/features/email-confirmation/index.tsx @@ -6,6 +6,7 @@ import { confirmChangedEmail } from 'soapbox/actions/security'; import snackbar from 'soapbox/actions/snackbar'; import { Spinner } from 'soapbox/components/ui'; import { useAppDispatch } from 'soapbox/hooks'; +import toast from 'soapbox/toast'; import { buildErrorMessage } from 'soapbox/utils/errors'; const Statuses = { @@ -32,11 +33,7 @@ const EmailConfirmation = () => { .then(() => { setStatus(Statuses.SUCCESS); - dispatch( - snackbar.success( - intl.formatMessage(messages.success), - ), - ); + toast.success(intl.formatMessage(messages.success)); }) .catch((error) => { setStatus(Statuses.FAIL); diff --git a/app/soapbox/features/migration/index.tsx b/app/soapbox/features/migration/index.tsx index edf8ea6f7..bede0278e 100644 --- a/app/soapbox/features/migration/index.tsx +++ b/app/soapbox/features/migration/index.tsx @@ -6,6 +6,7 @@ import { moveAccount } from 'soapbox/actions/security'; import snackbar from 'soapbox/actions/snackbar'; import { Button, Column, Form, FormActions, FormGroup, Input, Text } from 'soapbox/components/ui'; import { useAppDispatch, useInstance } from 'soapbox/hooks'; +import toast from 'soapbox/toast'; const messages = defineMessages({ heading: { id: 'column.migration', defaultMessage: 'Account migration' }, @@ -43,7 +44,7 @@ const Migration = () => { setIsLoading(true); return dispatch(moveAccount(targetAccount, password)).then(() => { clearForm(); - dispatch(snackbar.success(intl.formatMessage(messages.moveAccountSuccess))); + toast.success(intl.formatMessage(messages.moveAccountSuccess)); }).catch(error => { let message = intl.formatMessage(messages.moveAccountFail); diff --git a/app/soapbox/features/security/mfa/disable-otp-form.tsx b/app/soapbox/features/security/mfa/disable-otp-form.tsx index 63a551f31..2545732a7 100644 --- a/app/soapbox/features/security/mfa/disable-otp-form.tsx +++ b/app/soapbox/features/security/mfa/disable-otp-form.tsx @@ -6,6 +6,7 @@ import { disableMfa } from 'soapbox/actions/mfa'; import snackbar from 'soapbox/actions/snackbar'; import { Button, Form, FormGroup, Input, FormActions, Stack, Text } from 'soapbox/components/ui'; import { useAppDispatch } from 'soapbox/hooks'; +import toast from 'soapbox/toast'; const messages = defineMessages({ mfa_setup_disable_button: { id: 'column.mfa_disable_button', defaultMessage: 'Disable' }, @@ -25,7 +26,7 @@ const DisableOtpForm: React.FC = () => { const handleSubmit = useCallback(() => { setIsLoading(true); dispatch(disableMfa('totp', password)).then(() => { - dispatch(snackbar.success(intl.formatMessage(messages.mfaDisableSuccess))); + toast.success(intl.formatMessage(messages.mfaDisableSuccess)); history.push('../auth/edit'); }).finally(() => { setIsLoading(false); diff --git a/app/soapbox/features/security/mfa/otp-confirm-form.tsx b/app/soapbox/features/security/mfa/otp-confirm-form.tsx index 76f2ae45b..99e307e12 100644 --- a/app/soapbox/features/security/mfa/otp-confirm-form.tsx +++ b/app/soapbox/features/security/mfa/otp-confirm-form.tsx @@ -10,6 +10,7 @@ import { import snackbar from 'soapbox/actions/snackbar'; import { Button, Form, FormActions, FormGroup, Input, Stack, Text } from 'soapbox/components/ui'; import { useAppDispatch } from 'soapbox/hooks'; +import toast from 'soapbox/toast'; const messages = defineMessages({ mfaCancelButton: { id: 'column.mfa_cancel', defaultMessage: 'Cancel' }, @@ -52,7 +53,7 @@ const OtpConfirmForm: React.FC = () => { setState((prevState) => ({ ...prevState, isLoading: true })); dispatch(confirmMfa('totp', state.code, state.password) as any).then((r: any) => { - dispatch(snackbar.success(intl.formatMessage(messages.mfaConfirmSuccess))); + toast.success(intl.formatMessage(messages.mfaConfirmSuccess)); history.push('../auth/edit'); }).catch(() => { dispatch(snackbar.error(intl.formatMessage(messages.confirmFail))); diff --git a/app/soapbox/features/soapbox-config/index.tsx b/app/soapbox/features/soapbox-config/index.tsx index 315e78adf..dc1ebdb0e 100644 --- a/app/soapbox/features/soapbox-config/index.tsx +++ b/app/soapbox/features/soapbox-config/index.tsx @@ -5,7 +5,6 @@ import { useHistory } from 'react-router-dom'; import { updateSoapboxConfig } from 'soapbox/actions/admin'; import { uploadMedia } from 'soapbox/actions/media'; -import snackbar from 'soapbox/actions/snackbar'; import List, { ListItem } from 'soapbox/components/list'; import { Accordion, @@ -25,6 +24,7 @@ import { import ThemeSelector from 'soapbox/features/ui/components/theme-selector'; import { useAppSelector, useAppDispatch, useFeatures } from 'soapbox/hooks'; import { normalizeSoapboxConfig } from 'soapbox/normalizers'; +import toast from 'soapbox/toast'; import CryptoAddressInput from './components/crypto-address-input'; import FooterLinkInput from './components/footer-link-input'; @@ -102,7 +102,7 @@ const SoapboxConfig: React.FC = () => { const handleSubmit: React.FormEventHandler = (e) => { dispatch(updateSoapboxConfig(data.toJS())).then(() => { setLoading(false); - dispatch(snackbar.success(intl.formatMessage(messages.saved))); + toast.success(intl.formatMessage(messages.saved)); }).catch(() => { setLoading(false); }); diff --git a/app/soapbox/features/theme-editor/index.tsx b/app/soapbox/features/theme-editor/index.tsx index 35e94882e..43a474253 100644 --- a/app/soapbox/features/theme-editor/index.tsx +++ b/app/soapbox/features/theme-editor/index.tsx @@ -4,7 +4,6 @@ import { v4 as uuidv4 } from 'uuid'; import { updateSoapboxConfig } from 'soapbox/actions/admin'; import { getHost } from 'soapbox/actions/instance'; -import snackbar from 'soapbox/actions/snackbar'; import { fetchSoapboxConfig } from 'soapbox/actions/soapbox'; import List, { ListItem } from 'soapbox/components/list'; import { Button, Column, Form, FormActions } from 'soapbox/components/ui'; @@ -12,6 +11,7 @@ import DropdownMenuContainer from 'soapbox/containers/dropdown-menu-container'; import ColorWithPicker from 'soapbox/features/soapbox-config/components/color-with-picker'; import { useAppDispatch, useAppSelector, useSoapboxConfig } from 'soapbox/hooks'; import { normalizeSoapboxConfig } from 'soapbox/normalizers'; +import toast from 'soapbox/toast'; import { download } from 'soapbox/utils/download'; import Palette, { ColorGroup } from './components/palette'; @@ -103,7 +103,7 @@ const ThemeEditor: React.FC = () => { const colors = normalizeSoapboxConfig({ colors: json }).colors.toJS(); setTheme(colors); - dispatch(snackbar.success(intl.formatMessage(messages.importSuccess))); + toast.success(intl.formatMessage(messages.importSuccess)); } }; @@ -113,7 +113,7 @@ const ThemeEditor: React.FC = () => { try { await dispatch(fetchSoapboxConfig(host)); await updateTheme(); - dispatch(snackbar.success(intl.formatMessage(messages.saved))); + toast.success(intl.formatMessage(messages.saved)); setSubmitting(false); } catch (e) { setSubmitting(false); @@ -199,7 +199,7 @@ const ThemeEditor: React.FC = () => { text: intl.formatMessage(messages.restore), action: restoreDefaultTheme, icon: require('@tabler/icons/refresh.svg'), - },{ + }, { text: intl.formatMessage(messages.import), action: importTheme, icon: require('@tabler/icons/upload.svg'), diff --git a/app/soapbox/features/ui/components/modals/account-moderation-modal/account-moderation-modal.tsx b/app/soapbox/features/ui/components/modals/account-moderation-modal/account-moderation-modal.tsx index 264ffcfb4..bd075cd54 100644 --- a/app/soapbox/features/ui/components/modals/account-moderation-modal/account-moderation-modal.tsx +++ b/app/soapbox/features/ui/components/modals/account-moderation-modal/account-moderation-modal.tsx @@ -9,7 +9,6 @@ import { setBadges as saveBadges, } from 'soapbox/actions/admin'; import { deactivateUserModal, deleteUserModal } from 'soapbox/actions/moderation'; -import snackbar from 'soapbox/actions/snackbar'; import Account from 'soapbox/components/account'; import List, { ListItem } from 'soapbox/components/list'; import MissingIndicator from 'soapbox/components/missing-indicator'; @@ -17,6 +16,7 @@ import OutlineBox from 'soapbox/components/outline-box'; import { Button, Text, HStack, Modal, Stack, Toggle } from 'soapbox/components/ui'; import { useAppDispatch, useAppSelector, useFeatures, useOwnAccount } from 'soapbox/hooks'; import { makeGetAccount } from 'soapbox/selectors'; +import toast from 'soapbox/toast'; import { isLocal } from 'soapbox/utils/accounts'; import { getBadges } from 'soapbox/utils/badges'; @@ -75,7 +75,7 @@ const AccountModerationModal: React.FC = ({ onClose, ac const action = checked ? verifyUser : unverifyUser; dispatch(action(account.id)) - .then(() => dispatch(snackbar.success(intl.formatMessage(message, { acct: account.acct })))) + .then(() => toast.success(intl.formatMessage(message, { acct: account.acct }))) .catch(() => {}); }; @@ -86,7 +86,7 @@ const AccountModerationModal: React.FC = ({ onClose, ac const action = checked ? suggestUsers : unsuggestUsers; dispatch(action([account.id])) - .then(() => dispatch(snackbar.success(intl.formatMessage(message, { acct: account.acct })))) + .then(() => toast.success(intl.formatMessage(message, { acct: account.acct }))) .catch(() => {}); }; @@ -100,7 +100,7 @@ const AccountModerationModal: React.FC = ({ onClose, ac const handleSaveBadges = () => { dispatch(saveBadges(account.id, accountBadges, badges)) - .then(() => dispatch(snackbar.success(intl.formatMessage(messages.badgesSaved)))) + .then(() => toast.success(intl.formatMessage(messages.badgesSaved))) .catch(() => {}); }; diff --git a/app/soapbox/features/ui/components/modals/account-moderation-modal/staff-role-picker.tsx b/app/soapbox/features/ui/components/modals/account-moderation-modal/staff-role-picker.tsx index 30502d427..3bb46d228 100644 --- a/app/soapbox/features/ui/components/modals/account-moderation-modal/staff-role-picker.tsx +++ b/app/soapbox/features/ui/components/modals/account-moderation-modal/staff-role-picker.tsx @@ -2,9 +2,9 @@ import React, { useMemo } from 'react'; import { defineMessages, MessageDescriptor, useIntl } from 'react-intl'; import { setRole } from 'soapbox/actions/admin'; -import snackbar from 'soapbox/actions/snackbar'; import { SelectDropdown } from 'soapbox/features/forms'; import { useAppDispatch } from 'soapbox/hooks'; +import toast from 'soapbox/toast'; import type { Account as AccountEntity } from 'soapbox/types/entities'; @@ -66,7 +66,7 @@ const StaffRolePicker: React.FC = ({ account }) => { } if (message) { - dispatch(snackbar.success(intl.formatMessage(message, { acct: account.acct }))); + toast.success(intl.formatMessage(message, { acct: account.acct })); } }) .catch(() => {}); diff --git a/app/soapbox/features/ui/components/modals/edit-federation-modal.tsx b/app/soapbox/features/ui/components/modals/edit-federation-modal.tsx index 2d3e15872..55a91ae1f 100644 --- a/app/soapbox/features/ui/components/modals/edit-federation-modal.tsx +++ b/app/soapbox/features/ui/components/modals/edit-federation-modal.tsx @@ -4,11 +4,11 @@ import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import Toggle from 'react-toggle'; import { updateMrf } from 'soapbox/actions/mrf'; -import snackbar from 'soapbox/actions/snackbar'; import List, { ListItem } from 'soapbox/components/list'; import { Modal } from 'soapbox/components/ui'; import { useAppSelector, useAppDispatch } from 'soapbox/hooks'; import { makeGetRemoteInstance } from 'soapbox/selectors'; +import toast from 'soapbox/toast'; const messages = defineMessages({ mediaRemoval: { id: 'edit_federation.media_removal', defaultMessage: 'Strip media' }, @@ -56,7 +56,7 @@ const EditFederationModal: React.FC = ({ host, onClose }) const handleSubmit = () => { dispatch(updateMrf(host, data)) - .then(() => dispatch(snackbar.success(intl.formatMessage(messages.success, { host })))) + .then(() => toast.success(intl.formatMessage(messages.success, { host }))) .catch(() => {}); onClose(); diff --git a/app/soapbox/features/ui/components/modals/verify-sms-modal.tsx b/app/soapbox/features/ui/components/modals/verify-sms-modal.tsx index a6d327272..4bf23b4d0 100644 --- a/app/soapbox/features/ui/components/modals/verify-sms-modal.tsx +++ b/app/soapbox/features/ui/components/modals/verify-sms-modal.tsx @@ -8,6 +8,7 @@ import snackbar from 'soapbox/actions/snackbar'; import { reConfirmPhoneVerification, reRequestPhoneVerification } from 'soapbox/actions/verification'; import { FormGroup, PhoneInput, Modal, Stack, Text } from 'soapbox/components/ui'; import { useAppDispatch, useAppSelector, useInstance } from 'soapbox/hooks'; +import toast from 'soapbox/toast'; import { getAccessToken } from 'soapbox/utils/auth'; const messages = defineMessages({ @@ -85,10 +86,8 @@ const VerifySmsModal: React.FC = ({ onClose }) => { } dispatch(reRequestPhoneVerification(phone!)).then(() => { - dispatch( - snackbar.success( - intl.formatMessage(messages.verificationSuccess), - ), + toast.success( + intl.formatMessage(messages.verificationSuccess), ); }) .finally(() => setStatus(Statuses.REQUESTED)) diff --git a/app/soapbox/features/ui/components/subscription-button.tsx b/app/soapbox/features/ui/components/subscription-button.tsx index 8080a7c52..6c49b66bd 100644 --- a/app/soapbox/features/ui/components/subscription-button.tsx +++ b/app/soapbox/features/ui/components/subscription-button.tsx @@ -9,6 +9,7 @@ import { import snackbar from 'soapbox/actions/snackbar'; import { IconButton } from 'soapbox/components/ui'; import { useAppDispatch, useFeatures } from 'soapbox/hooks'; +import toast from 'soapbox/toast'; import type { Account as AccountEntity } from 'soapbox/types/entities'; @@ -40,13 +41,13 @@ const SubscriptionButton = ({ account }: ISubscriptionButton) => { intl.formatMessage(messages.subscribe, { name: account.get('username') }); const onSubscribeSuccess = () => - dispatch(snackbar.success(intl.formatMessage(messages.subscribeSuccess))); + toast.success(intl.formatMessage(messages.subscribeSuccess)); const onSubscribeFailure = () => dispatch(snackbar.error(intl.formatMessage(messages.subscribeFailure))); const onUnsubscribeSuccess = () => - dispatch(snackbar.success(intl.formatMessage(messages.unsubscribeSuccess))); + toast.success(intl.formatMessage(messages.unsubscribeSuccess)); const onUnsubscribeFailure = () => dispatch(snackbar.error(intl.formatMessage(messages.unsubscribeFailure))); diff --git a/app/soapbox/features/verification/email-passthru.tsx b/app/soapbox/features/verification/email-passthru.tsx index bfdc017de..aaea39f58 100644 --- a/app/soapbox/features/verification/email-passthru.tsx +++ b/app/soapbox/features/verification/email-passthru.tsx @@ -6,6 +6,7 @@ import snackbar from 'soapbox/actions/snackbar'; import { confirmEmailVerification } from 'soapbox/actions/verification'; import { Icon, Spinner, Stack, Text } from 'soapbox/components/ui'; import { useAppDispatch, useAppSelector } from 'soapbox/hooks'; +import toast from 'soapbox/toast'; import { ChallengeTypes } from './index'; @@ -121,7 +122,7 @@ const EmailPassThru = () => { dispatch(confirmEmailVerification(token)) .then(() => { setStatus(Statuses.SUCCESS); - dispatch(snackbar.success(intl.formatMessage(messages.emailConfirmed))); + toast.success(intl.formatMessage(messages.emailConfirmed)); }) .catch((error: AxiosError) => { const errorKey = error?.response?.data?.error; diff --git a/app/soapbox/features/verification/registration.tsx b/app/soapbox/features/verification/registration.tsx index d19eb03d9..4c9549cc1 100644 --- a/app/soapbox/features/verification/registration.tsx +++ b/app/soapbox/features/verification/registration.tsx @@ -9,6 +9,7 @@ import snackbar from 'soapbox/actions/snackbar'; import { createAccount, removeStoredVerification } from 'soapbox/actions/verification'; import { Button, Form, FormGroup, Input, Text } from 'soapbox/components/ui'; import { useAppDispatch, useAppSelector, useInstance, useSoapboxConfig } from 'soapbox/hooks'; +import toast from 'soapbox/toast'; import { getRedirectUrl } from 'soapbox/utils/redirect'; import PasswordIndicator from './components/password-indicator'; @@ -54,10 +55,8 @@ const Registration = () => { setShouldRedirect(true); removeStoredVerification(); dispatch(startOnboarding()); - dispatch( - snackbar.success( - intl.formatMessage(messages.success, { siteTitle: instance.title }), - ), + toast.success( + intl.formatMessage(messages.success, { siteTitle: instance.title }), ); }) .catch((error: AxiosError) => { diff --git a/app/soapbox/features/verification/steps/email-verification.tsx b/app/soapbox/features/verification/steps/email-verification.tsx index a83483616..f88dafa76 100644 --- a/app/soapbox/features/verification/steps/email-verification.tsx +++ b/app/soapbox/features/verification/steps/email-verification.tsx @@ -2,11 +2,11 @@ import { AxiosError } from 'axios'; import React from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; -import snackbar from 'soapbox/actions/snackbar'; import { checkEmailVerification, postEmailVerification, requestEmailVerification } from 'soapbox/actions/verification'; import Icon from 'soapbox/components/icon'; import { Button, Form, FormGroup, Input, Text } from 'soapbox/components/ui'; import { useAppDispatch, useAppSelector } from 'soapbox/hooks'; +import toast from 'soapbox/toast'; const messages = defineMessages({ verificationSuccess: { id: 'email_verification.success', defaultMessage: 'Verification email sent successfully.' }, @@ -83,11 +83,7 @@ const EmailVerification = () => { .then(() => { setStatus(Statuses.REQUESTED); - dispatch( - snackbar.success( - intl.formatMessage(messages.verificationSuccess), - ), - ); + toast.success(intl.formatMessage(messages.verificationSuccess)); }) .catch((error: AxiosError) => { const errorMessage = (error.response?.data as any)?.error; @@ -104,7 +100,7 @@ const EmailVerification = () => { setErrors([intl.formatMessage(messages.verificationFailTaken)]); } - dispatch(snackbar.error(message)); + toast.error(message); setStatus(Statuses.FAIL); }); }; diff --git a/app/soapbox/features/verification/steps/sms-verification.tsx b/app/soapbox/features/verification/steps/sms-verification.tsx index efe0a5ffc..e38d54f35 100644 --- a/app/soapbox/features/verification/steps/sms-verification.tsx +++ b/app/soapbox/features/verification/steps/sms-verification.tsx @@ -3,10 +3,10 @@ import React from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import OtpInput from 'react-otp-input'; -import snackbar from 'soapbox/actions/snackbar'; import { confirmPhoneVerification, requestPhoneVerification } from 'soapbox/actions/verification'; import { Button, Form, FormGroup, PhoneInput, Text } from 'soapbox/components/ui'; import { useAppDispatch, useAppSelector } from 'soapbox/hooks'; +import toast from 'soapbox/toast'; const messages = defineMessages({ verificationInvalid: { id: 'sms_verification.invalid', defaultMessage: 'Please enter a valid phone number.' }, @@ -44,25 +44,17 @@ const SmsVerification = () => { if (!isValid) { setStatus(Statuses.IDLE); - dispatch( - snackbar.error( - intl.formatMessage(messages.verificationInvalid), - ), - ); + toast.error(intl.formatMessage(messages.verificationInvalid)); return; } dispatch(requestPhoneVerification(phone!)).then(() => { - dispatch( - snackbar.success( - intl.formatMessage(messages.verificationSuccess), - ), - ); + toast.success(intl.formatMessage(messages.verificationSuccess)); setStatus(Statuses.REQUESTED); }).catch((error: AxiosError) => { const message = (error.response?.data as any)?.message || intl.formatMessage(messages.verificationFail); - dispatch(snackbar.error(message)); + toast.error(message); setStatus(Statuses.FAIL); }); }, [phone, isValid]); @@ -75,11 +67,9 @@ const SmsVerification = () => { const submitVerification = () => { // TODO: handle proper validation from Pepe -- expired vs invalid dispatch(confirmPhoneVerification(verificationCode)) - .catch(() => dispatch( - snackbar.error( - intl.formatMessage(messages.verificationExpired), - ), - )); + .catch(() => { + toast.error(intl.formatMessage(messages.verificationExpired)); + }); }; React.useEffect(() => { diff --git a/app/soapbox/queries/accounts.ts b/app/soapbox/queries/accounts.ts index 75d1193f6..20ec74188 100644 --- a/app/soapbox/queries/accounts.ts +++ b/app/soapbox/queries/accounts.ts @@ -1,8 +1,8 @@ import { useMutation } from '@tanstack/react-query'; import { patchMeSuccess } from 'soapbox/actions/me'; -import snackbar from 'soapbox/actions/snackbar'; import { useApi, useAppDispatch, useOwnAccount } from 'soapbox/hooks'; +import toast from 'soapbox/toast'; export type IAccount = { acct: string @@ -48,10 +48,10 @@ const useUpdateCredentials = () => { }, onSuccess(response) { dispatch(patchMeSuccess(response.data)); - dispatch(snackbar.success('Chat Settings updated successfully')); + toast.success('Chat Settings updated successfully'); }, onError(_error, _variables, context: any) { - dispatch(snackbar.error('Chat Settings failed to update.')); + toast.error('Chat Settings failed to update.'); dispatch(patchMeSuccess(context.cachedAccount)); }, }); diff --git a/app/soapbox/queries/chats.ts b/app/soapbox/queries/chats.ts index 4c377abb7..261122819 100644 --- a/app/soapbox/queries/chats.ts +++ b/app/soapbox/queries/chats.ts @@ -2,12 +2,12 @@ import { InfiniteData, useInfiniteQuery, useMutation, useQuery } from '@tanstack import sumBy from 'lodash/sumBy'; import { importFetchedAccount, importFetchedAccounts } from 'soapbox/actions/importer'; -import snackbar from 'soapbox/actions/snackbar'; import { getNextLink } from 'soapbox/api'; import { ChatWidgetScreens, useChatContext } from 'soapbox/contexts/chat-context'; import { useStatContext } from 'soapbox/contexts/stat-context'; import { useApi, useAppDispatch, useAppSelector, useFeatures, useOwnAccount } from 'soapbox/hooks'; import { normalizeChatMessage } from 'soapbox/normalizers'; +import toast from 'soapbox/toast'; import { reOrderChatListItems } from 'soapbox/utils/chats'; import { flattenPages, PaginatedResult, updatePageItem } from 'soapbox/utils/queries'; @@ -203,7 +203,7 @@ const useChat = (chatId?: string) => { const useChatActions = (chatId: string) => { const account = useOwnAccount(); const api = useApi(); - const dispatch = useAppDispatch(); + // const dispatch = useAppDispatch(); const { setUnreadChatsCount } = useStatContext(); @@ -307,12 +307,12 @@ const useChatActions = (chatId: string) => { onError: (_error: any, _newData: any, context: any) => { changeScreen(ChatWidgetScreens.CHAT, context.prevChat.id); queryClient.setQueryData(ChatKeys.chat(chatId), context.prevChat); - dispatch(snackbar.error('Chat Settings failed to update.')); + toast.error('Chat Settings failed to update.'); }, onSuccess() { queryClient.invalidateQueries(ChatKeys.chat(chatId)); queryClient.invalidateQueries(ChatKeys.chatSearch()); - dispatch(snackbar.success('Chat Settings updated successfully')); + toast.success('Chat Settings updated successfully'); }, });